如何通过prepareForSegue:一个对象
我在mapview中有很多注释(带有rightCalloutAccessory
button)。 button将从这个mapview
执行一个segue到一个tableview
。 我想通过tableview
不同的对象(保存数据)取决于哪个标注button被点击。
例如:(完全组成)
- annotation1(Austin) – >传递数据obj 1(与奥斯丁有关)
- annotation2(达拉斯) – >传递数据obj 2(与达拉斯相关)
- annotation3(休斯敦) – >传递数据obj 3等…(你明白了)
我能够检测哪个标注button被点击。
我正在使用prepareForSegue
:将数据obj传递到目标ViewController
。 由于我不能让这个调用为我所需要的数据obj额外的参数,什么是一些优雅的方式来实现相同的效果(dynamic数据对象)?
任何提示将不胜感激。
只需在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]; } }
REVISION:您也可以使用performSegueWithIdentifier:sender:
方法来激活到基于select或button按下的新视图的转换。
例如,考虑我有两个视图控制器。 第一个包含三个button,第二个需要知道在转换之前按下了哪些button。 你可以将button连接到你的代码中使用performSegueWithIdentifier:
方法的IBAction
,就像这样…
// 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]; } }
编辑:我最初附加的演示应用程序现在是六岁,所以我已经删除它,以避免任何混淆。
接受的答案不是这样做的最好方法,因为它会在两个视图控制器之间创build不必要的编译时间依赖性。 以下是如何做到这一点,而不关心目标视图控制器的types:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.destinationViewController respondsToSelector:@selector(setMyData:)]) { [segue.destinationViewController performSelector:@selector(setMyData:) withObject:myData]; } }
所以只要您的目标视图控制器声明一个公共属性,例如:
@property (nonatomic, strong) MyData *myData;
您可以在上面的视图控制器中设置此属性,如上所述。
我有一个发件人类 ,就像这样
@class MyEntry; @interface MySenderEntry : NSObject @property (strong, nonatomic) MyEntry *entry; @end @implementation MySenderEntry @end
我使用这个发件人类传递对象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; } }
在Swift中我会做这样的事情:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let yourVC = segue.destinationViewController as? YourViewController { yourVC.yourData = self.someData } }
当我试图学习如何将数据从一个视图控制器传递到另一个时,我遇到了这个问题。 我需要一些视觉帮助我学习,所以这个答案是已经在这里的其他人的补充。 这是比原来的问题更普遍一些,但它可以适应工作。
这个基本的例子是这样的:
这个想法是将一个string从第一个视图控制器中的文本字段传递到第二个视图控制器中的标签。
第一视图控制器
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 } }
记得
- 通过控制点击button并将其拖放到第二个视图控制器来实现轮巡。
- 连接
UITextField
和UILabel
的sockets。 - 将第一个和第二个视图控制器设置为IB中合适的Swift文件。
资源
如何通过segue(swift)发送数据 (YouTube教程)
也可以看看
视图控制器:传递数据并传回数据 (更完整的答案)
我已经实现了一个UIViewController类别的库,简化了这个操作。 基本上,你可以在一个NSDictionary中设置你想要传递的参数,这个NSDictionary与正在执行segue的UI项目相关联。 它也适用于手动游戏。
例如,你可以做
[self performSegueWithIdentifier:@"yourIdentifier" parameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
对于手动的segue或创build一个button和一个segue和使用
[button setSegueParameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
如果目标视图控制器不是按键的键值编码,则没有任何反应。 它也可以与键值一起工作(对于展开顺序非常有用)。 看看这里https://github.com/stefanomondino/SMQuickSegue
对于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! } }
我的解决scheme是类似的
// 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 } }
我使用这个解决scheme,以便可以在同一个函数中保持segue和数据通信的调用:
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) }
用例如下所示:
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 } } }
这似乎为我工作,但是,我不是100%确定执行和准备function始终在同一个线程上执行。