How to pass prepareForSegue: an object

后端 未结 10 2057
北荒
北荒 2020-11-21 11:18

I have many annotations in a mapview (with rightCalloutAccessory buttons). The button will perform a segue from this mapview to a tableview

相关标签:
10条回答
  • 2020-11-21 11:36

    In Swift 4.2 I would do something like that:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let yourVC = segue.destination as? YourViewController {
            yourVC.yourData = self.someData
        }
    }
    
    0 讨论(0)
  • 2020-11-21 11:39

    I've implemented a library with a category on UIViewController that simplifies this operation. Basically, you set the parameters you want to pass over in a NSDictionary associated to the UI item that is performing the segue. It works with manual segues too.

    For example, you can do

    [self performSegueWithIdentifier:@"yourIdentifier" parameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
    

    for a manual segue or create a button with a segue and use

    [button setSegueParameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
    

    If destination view controller is not key-value coding compliant for a key, nothing happens. It works with key-values too (useful for unwind segues). Check it out here https://github.com/stefanomondino/SMQuickSegue

    0 讨论(0)
  • 2020-11-21 11:40

    I have a sender class, like this

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

    I use this sender class for passing objects to 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;
        }
    }
    
    0 讨论(0)
  • 2020-11-21 11:40

    I used this solution so that I could keep the invocation of the segue and the data communication within the same function:

    private var segueCompletion : ((UIStoryboardSegue, Any?) -> Void)?
    
    func performSegue(withIdentifier identifier: String, sender: Any?, completion: @escaping (UIStoryboardSegue, Any?) -> Void) {
        self.segueCompletion = completion;
        self.performSegue(withIdentifier: identifier, sender: sender);
        self.segueCompletion = nil
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        self.segueCompletion?(segue, sender)
    }
    

    A use case would be something like:

    func showData(id : Int){
        someService.loadSomeData(id: id) {
            data in
            self.performSegue(withIdentifier: "showData", sender: self) {
                storyboard, sender in
                let dataView = storyboard.destination as! DataView
                dataView.data = data
            }
        }
    }
    

    This seems to work for me, however, I'm not 100% sure that the perform and prepare functions are always executed on the same thread.

    0 讨论(0)
  • 2020-11-21 11:41

    My solution is similar.

    // In destination class: 
    var AddressString:String = String()
    
    // In segue:
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
       if (segue.identifier == "seguetobiddetailpagefromleadbidder")
        {
            let secondViewController = segue.destinationViewController as! BidDetailPage
            secondViewController.AddressString = pr.address as String
        }
    }
    
    0 讨论(0)
  • 2020-11-21 11:43

    I came across this question when I was trying to learn how to pass data from one View Controller to another. I need something visual to help me learn though, so this answer is a supplement to the others already here. It is a little more general than the original question but it can be adapted to work.

    This basic example works like this:

    The idea is to pass a string from the text field in the First View Controller to the label in the Second View Controller.

    First 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!
        }
    
    }
    

    Second View Controller

    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
        }
    
    }
    

    Remember to

    • Make the segue by control clicking on the button and draging it over to the Second View Controller.
    • Hook up the outlets for the UITextField and the UILabel.
    • Set the first and second View Controllers to the appropriate Swift files in IB.

    Source

    How to send data through segue (swift) (YouTube tutorial)

    See also

    View Controllers: Passing data forward and passing data back (fuller answer)

    0 讨论(0)
提交回复
热议问题