I have many annotations in a mapview (with rightCalloutAccessory
buttons). The button will perform a segue from this mapview
to a tableview
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
}
}
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
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;
}
}
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.
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
}
}
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.
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!
}
}
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
}
}
UITextField
and the UILabel
.How to send data through segue (swift) (YouTube tutorial)
View Controllers: Passing data forward and passing data back (fuller answer)