我在mapview中有许多注释(与rightCalloutAccessory按钮)。该按钮将执行一个从mapview到tableview的segue。我想传递给tableview一个不同的对象(持有数据),这取决于哪个callout按钮被单击。
例如:(完全是瞎编的)
注释1 (Austin) ->传递数据obj 1(与Austin相关)
注释2(达拉斯)->传递数据obj 2(有关达拉斯)
注释3(休斯顿)->传递数据obj 3等等…(你会得到
主意)
我能够检测到哪个调出按钮被单击。
我使用prepareForSegue:来传递数据对象到目标ViewController。由于我不能使这个调用为我需要的数据对象额外的参数,有什么优雅的方法来实现相同的效果(动态数据对象)?
任何建议都将不胜感激。
有时避免在两个视图控制器之间创建编译时依赖关系是有帮助的。下面是你不用关心目标视图控制器的类型就能做到的方法:
- (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函数总是在同一个线程上执行。