将数据从一个视图控制器传递到另一个视图iOS< = 4 vs iOS 5

时间:2012-01-01 16:36:15

标签: ios uinavigationcontroller ios5

首先,一点背景。我是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并谨慎对待风?

3 个答案:

答案 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,并且可以轻松地将其替换为支持处理公司的另一个。