如何传递prepareForSegue:一个对象

chi*_*zle 357 xcode storyboard uitableview mapkit ios

我在mapview中有很多注释(带rightCalloutAccessory按钮).该按钮将执行从此mapview到a 的segue tableview.我想传递tableview一个不同的对象(保存数据),具体取决于单击了哪个标注按钮.

例如:(完全组成)

  • annotation1(奥斯汀) - >传递数据obj 1(与奥斯汀相关)
  • annotation2(达拉斯) - >传递数据obj 2(与达拉斯有关)
  • annotation3(休斯敦) - >传递数据obj 3等等......(你明白了)

我能够检测到哪个标注按钮被点击了.

我正在使用prepareForSegue:将数据obj传递到目标ViewController.由于我无法进行此调用,因此需要为我需要的数据提供额外的参数,有哪些优雅的方法可以实现相同的效果(动态数据obj)?

任何提示将不胜感激.

Sim*_*mon 673

只需在prepareForSegue:方法中获取对目标视图控制器的引用,并将所需的任何对象传递给那里.这是一个例子......

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"YOUR_SEGUE_NAME_HERE"])
    {
        // Get reference to the destination view controller
        YourViewController *vc = [segue destinationViewController];

        // Pass any objects to the view controller here, like...
        [vc setMyObjectHere:object];
    }
}
Run Code Online (Sandbox Code Playgroud)

修订:您还可以使用performSegueWithIdentifier:sender:方法根据选择或按下按钮激活转换到新视图.

例如,考虑我有两个视图控制器.第一个包含三个按钮,第二个按钮需要知道在转换之前按下了哪些按钮.您可以将按钮连接到IBAction代码中使用performSegueWithIdentifier:方法,就像这样......

// When any of my buttons are pressed, push the next view
- (IBAction)buttonPressed:(id)sender
{
    [self performSegueWithIdentifier:@"MySegue" sender:sender];
}

// This will get called too before the view appears
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"MySegue"]) {

        // Get destination view
        SecondView *vc = [segue destinationViewController];

        // Get button tag number (or do whatever you need to do here, based on your object
        NSInteger tagIndex = [(UIButton *)sender tag];

        // Pass the information to your destination view
        [vc setSelectedButton:tagIndex];
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:我最初附加的演示应用程序现在已有六年了,所以我删除它以避免任何混淆.

  • 我已经用我可以下载的可下载示例更新了我的帖子. (2认同)

Mac*_*tle 82

有时,避免在两个视图控制器之间创建编译时依赖项是有帮助的.以下是如何在不关心目标视图控制器类型的情况下执行此操作:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.destinationViewController respondsToSelector:@selector(setMyData:)]) {
        [segue.destinationViewController performSelector:@selector(setMyData:) 
                                              withObject:myData];
    } 
}
Run Code Online (Sandbox Code Playgroud)

因此,只要目标视图控制器声明公共属性,例如:

@property (nonatomic, strong) MyData *myData;
Run Code Online (Sandbox Code Playgroud)

您可以在上一个视图控制器中设置此属性,如上所述.

  • 这种方法绝对会创建依赖关系,因为您需要目标视图控制器具有`setMyData:`.这是一种依赖.您使用选择器来避免编译错误的事实应该被视为您的方法的*弱点*,而不是一个好处.令我震惊的是,有多少开发人员已经失去了编译时错误应优先于运行时错误的概念. (14认同)
  • 这真的是一个意见问题.我还没有(我)没有想要严格控制视图控制器的情况,尽管我很欣赏你所说的内容,但在适当的情况下它可能很重要. (12认同)
  • 这不是一个意见问题,这是错误的:)"接受的答案不是这样做的最佳方式"是错误的.它应该是"在某些情况下,你需要这样做......" (10认同)
  • @Simon:是的,您只需选择最适合您的方法.例如,在我正在研究的应用程序中,我的方法很有意义,因为我不断添加需要相同数据对象的视图控制器.能够用一个segue连接它们并且知道它们将获得正确的数据是非常方便的. (2认同)
  • 我更喜欢西蒙的方法.因为它会在编译时告诉我错误.例如,如果我错过了目标视图控制器中myData的声明,我会马上知道.但对于您的方案,您的方法似乎很好! (2认同)

Rem*_*lia 20

在Swift 4.2中我会做类似的事情:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let yourVC = segue.destination as? YourViewController {
        yourVC.yourData = self.someData
    }
}
Run Code Online (Sandbox Code Playgroud)


neo*_*eye 16

我有一个发件人类,像这样

@class MyEntry;

@interface MySenderEntry : NSObject
@property (strong, nonatomic) MyEntry *entry;
@end

@implementation MySenderEntry
@end
Run Code Online (Sandbox Code Playgroud)

我使用此发送器类将对象传递给prepareForSeque:sender:

-(void)didSelectItemAtIndexPath:(NSIndexPath*)indexPath
{
    MySenderEntry *sender = [MySenderEntry new];
    sender.entry = [_entries objectAtIndex:indexPath.row];
    [self performSegueWithIdentifier:SEGUE_IDENTIFIER_SHOW_ENTRY sender:sender];
}

-(void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:SEGUE_IDENTIFIER_SHOW_ENTRY]) {
        NSAssert([sender isKindOfClass:[MySenderEntry class]], @"MySenderEntry");
        MySenderEntry *senderEntry = (MySenderEntry*)sender;
        MyEntry *entry = senderEntry.entry;
        NSParameterAssert(entry);

        [segue destinationViewController].delegate = self;
        [segue destinationViewController].entry = entry;
        return;
    }

    if ([[segue identifier] isEqualToString:SEGUE_IDENTIFIER_HISTORY]) {
        // ...
        return;
    }

    if ([[segue identifier] isEqualToString:SEGUE_IDENTIFIER_FAVORITE]) {
        // ...
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)


Sur*_*gch 14

当我试图学习如何将数据从一个View Controller传递到另一个时,我遇到了这个问题.我需要一些视觉来帮助我学习,所以这个答案是对其他人的补充.它比原始问题更为通用,但它可以适应工作.

这个基本示例的工作原理如下:

在此输入图像描述

我们的想法是将第一个视图控制器中的文本字段中的字符串传递给第二个视图控制器中的标签.

第一视图控制器

import UIKit

class FirstViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    // This function is called before the segue
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // get a reference to the second view controller
        let secondViewController = segue.destinationViewController as! SecondViewController

        // set a variable in the second view controller with the String to pass
        secondViewController.receivedString = textField.text!
    }

}
Run Code Online (Sandbox Code Playgroud)

第二视图控制器

import UIKit

class SecondViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    // This variable will hold the data being passed from the First View Controller
    var receivedString = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        // Used the text from the First View Controller to set the label
        label.text = receivedString
    }

}
Run Code Online (Sandbox Code Playgroud)

记得

  • 通过control单击按钮并将其拖到第二视图控制器来制作segue .
  • 挂钩的出口UITextFieldUILabel.
  • 将第一个和第二个View Controllers设置为IB中相应的Swift文件.

资源

如何通过segue(swift)发送数据(YouTube教程)

也可以看看

视图控制器:向前传递数据并传回数据(更全面的答案)


Zai*_*han 5

对于Swift来说,

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    var segueID = segue.identifier

    if(segueID! == "yourSegueName"){

        var yourVC:YourViewController = segue.destinationViewController as YourViewController

        yourVC.objectOnYourVC = setObjectValueHere!

    }
}
Run Code Online (Sandbox Code Playgroud)