我在mapview中有许多注释(与rightCalloutAccessory按钮)。该按钮将执行一个从mapview到tableview的segue。我想传递给tableview一个不同的对象(持有数据),这取决于哪个callout按钮被单击。
例如:(完全是瞎编的)
注释1 (Austin) ->传递数据obj 1(与Austin相关)
注释2(达拉斯)->传递数据obj 2(有关达拉斯)
注释3(休斯顿)->传递数据obj 3等等…(你会得到
主意)
我能够检测到哪个调出按钮被单击。
我使用prepareForSegue:来传递数据对象到目标ViewController。由于我不能使这个调用为我需要的数据对象额外的参数,有什么优雅的方法来实现相同的效果(动态数据对象)?
任何建议都将不胜感激。
只需要在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];
}
}
修改:您还可以使用performSegueWithIdentifier:sender:方法来激活基于选择或按钮按下的转换到新视图。
例如,假设我有两个视图控制器。第一个包含三个按钮,第二个需要知道在转换之前按下了哪个按钮。你可以在代码中使用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];
}
}
编辑:我最初附上的演示应用程序现在已经有6年了,所以我删除了它以避免任何混淆。
有时避免在两个视图控制器之间创建编译时依赖关系是有帮助的。下面是你不用关心目标视图控制器的类型就能做到的方法:
- (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;
你可以在前面的视图控制器中设置这个属性。
我使用这个解决方案,这样我就可以在同一个函数中保持对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%确定perform和prepare函数总是在同一个线程上执行。