我在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;
你可以在前面的视图控制器中设置这个属性。
我在UIViewController上实现了一个类库,简化了这个操作。
基本上,你在NSDictionary中设置你想要传递的参数与执行segue的uiitem关联。它也适用于手动segue。
例如,你可以这样做
[self performSegueWithIdentifier:@"yourIdentifier" parameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
对于手动segue或者创建一个带有segue的按钮并使用
[button setSegueParameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];
如果目标视图控制器不符合键的键值编码,什么都不会发生。它也适用于键值(对unwind segue很有用)。
点击这里查看
https://github.com/stefanomondino/SMQuickSegue
我有一个sender类,像这样
@class MyEntry;
@interface MySenderEntry : NSObject
@property (strong, nonatomic) MyEntry *entry;
@end
@implementation MySenderEntry
@end
我使用这个sender类来传递对象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;
}
}