首先,一点背景。我是iOS开发的新手,我已经在.Net上工作了很长时间,这可能就是为什么我甚至会问这个问题,但是这里也是。
基本设置是这样的。您有UINavigationController
RootViewController
我们会调用MasterViewController
。当在这个MasterViewController上发生某些动作时,我们想要深入研究DetailsViewController
。但是,我们还希望将一些数据传递给DetailsViewController
。
据我所知,在早期版本的SDK(iOS 5之前)中,这种方法与此类似:
@implementation MasterViewController
-(IBAction)someAction
{
DetailsViewController *dvc = [[DetailsViewController alloc]initWithNibName:@"DetailsView" bundle:nil];
dvc.someDataProp = [self getSomeDataSomeHow];
[[self navigationController] pushViewController:dvc animated:YES];
}
@end
然而,现在,在iOS 5中,似乎现在使用Storyboard和segues完成了这项工作。在XCode中,您将segue从MasterViewController设置为DetailsViewController,然后在代码中执行以下操作:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[segue.destinationViewController setSomeDataProp:[self getSomeDataSomeHow]];
}
我的问题基本上就是这样:对我来说,旧方法对我来说感觉更清洁。您非常清楚地了解了您正在推送到导航堆栈的ViewController
类型,并且您可以轻松地在其上设置属性。但是在新方法中,destinationViewController
的类型为id
(原因很明显),而且对我来说感觉不那么干净。再次,这可能是我的.Net方面出现,但这在iOS中常见吗?只是使用id并谨慎对待风?
答案 0 :(得分:6)
使用Storyboard,您可以为segue分配一个命名标识符, 选择segue,然后在属性检查器中,您可以为segue标识符添加名称。
在prepareForSegue方法中,您应该检查此标识符,因此您将明确知道将要执行哪个segue以及destinationViewController将是什么。
if ([segue.identifier isEqualToString:@"My First Segue Identifier"])
{
DetailsViewController *dvc = (DetailsViewController *) segue.destinationViewController;
// Set the DVC's properties
}
答案 1 :(得分:4)
在许多情况下,segue的目标视图控制器可能是UINavigationViewController,在这种情况下,解决方案(稍微修改Dennis Mathews的解决方案)将需要使用消息“topViewController”:
if ([segue.identifier isEqualToString:@"My First Segue Identifier"])
{
NavitationViewController* navController = [segue destinationViewController];
DetailsViewController *dvc = (DetailsViewController*) [navController topViewController]
// Set the DVC's properties
}
答案 2 :(得分:1)
我没有和iOS一起工作那么久,但是我已经看到了一些例子,你不必因为objective-c的松散耦合消息传递系统而进行投射。
您可以执行以下操作,而不是检查segue标识符或转换为特定的ViewController:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController respondsToSelector: @selector(setCompany:)]) {
[segue.destinationViewController performSelector: @selector(setCompany:) withObject: self.company];
}
}
在第一行中,我询问destinationViewController是否有方法setCompany(如果你有一个名为company的属性,那么将为你生成一个)。如果是,您可以使用第二行代码调用该方法/设置该属性。
因此,在这种情况下,您不必真正知道目标ViewController,并且可以轻松地将其替换为支持处理公司的另一个。