繁体   English   中英

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

[英]Passing data from one view controller to another; iOS <=4 vs iOS 5

首先,一点背景。 我是iOS开发的新手,我已经在.Net上呆了很长时间了,这也许就是为什么我甚至会问这个问题,但是这里也是如此。

基本设置是这样的。 你有一个带有RootViewControllerUINavigationController ,我们将调用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中,您将从MasterViewController设置为segue到DetailsViewController,然后在代码中执行以下操作:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
   [segue.destinationViewController setSomeDataProp:[self getSomeDataSomeHow]];
}

我的问题基本上是这样的:老方法对我来说感觉更清洁了。 您对正在推送到导航堆栈的ViewController的类型非常明确,您可以在其上轻松设置属性。 但是在新的方法中, destinationViewController的类型为id (出于显而易见的原因),它对我来说感觉不那么干净。 再次,这可能是我的.Net方面出现,但这在iOS中常见吗? 只是使用id并谨慎对待风?

使用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 
}

在许多情况下,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 
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM