2012-01-01 287 views
7

首先,有一点背景。我对iOS开发很陌生,很久以来我一直在.NET网站上,这可能就是为什么我甚至会问这个问题,但这里就是这样。将数据从一个视图控制器传递到另一个视图控制器; iOS <= 4 vs iOS 5

基本设置是这样的。你有一个UINavigationControllerRootViewController我们会打电话给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并继续。在Xcode中设置了从MasterViewController的SEGUE到DetailsViewController,然后在代码中你做这样的事情:

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

我的问题基本上是这样的:旧的做法在某种程度上感觉更清洁了很多给我。您正在非常明确地指出要推进导航堆栈的ViewController类型,并且您可以轻松地设置属性。但在新方法中,destinationViewController的类型为id(出于显而易见的原因),它对我来说感觉不那么干净。再次,这可能是我的.Net方面出来,但这在iOS中很常见?只需使用身份证,并谨慎对待风?

+1

非常尊重质疑如何做到这一点,而不是简单地复制和粘贴片段。我也有类似的问题,并在这里有一些经验是我的答案:在iOS5中,我看到UI逻辑被分成两部分:1)ViewController生命周期和转换2)数据流。Storyboard负责1,开发人员需要照顾2.在这种情况下,这些演员将会发生。对我而言,问题是,这种分裂是否有意义?这两个概念可以分离吗?我猜苹果会这样,我们会看到它是如何运作的。 – Guven 2012-04-10 16:17:32

回答

6

通过故事板,您可以为segue指定一个已命名的标识符, 选择segue并在属性检查器中为segue标识符添加名称。

而在prepareForSegue方法中,您应该检查此标识符,因此您将明确知道哪个segue将要执行以及destinationViewController将是什么。

​​
+0

更好,但你仍然有那么丑。这是首选的方法吗? – BFree 2012-01-01 17:25:20

+0

这是首选的方法。你是对的,旧的方式更清晰,更明确。用这种新方法,你可以“接入”故事板。不幸的是,只有在故事板中才能找到的新功能并未进入XIB设计器,例如新的静态和动态UITableView设计器支持。 – 2012-01-01 22:24:16

+1

是在'prepareForSegue'方法中插入了这段代码吗? – chwi 2012-07-31 08:54:05

4

在许多情况下,对于一个赛格瑞目的地视图控制器可以是UINavigationViewController,在这种情况下,溶液(上面丹尼斯Mathews的溶液轻微的修改)将需要使用消息‘topViewController’ :

if ([segue.identifier isEqualToString:@"My First Segue Identifier"]) 
{  
    NavitationViewController* navController = [segue destinationViewController]; 
    DetailsViewController *dvc = (DetailsViewController*) [navController topViewController] 
    // Set the DVC's properties 
} 
+0

这对我来说伎俩,除了我认为你的意思是“UINavigationController * navController”而不是“NavitationViewController * navController”。 – mpemburn 2012-06-25 23:27:42

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(如果你有一个名为物业公司这一个会为你生成)。如果是这样,您可以调用该方法/使用第二行代码设置该属性。

因此,在这种情况下,您并不需要知道目标ViewController,并且可以轻松地将其替换为支持处理公司的另一个。

相关问题