跨子导航控制器传递数据

时间:2012-03-23 00:24:42

标签: ios uinavigationcontroller segue

概述

我有一个iOS项目,其中包含2个导航控制器,如下图所示。

我希望在从AAA切换到CCC时传递一些数据,但在AAA和CCC之间有一个导航控制器。

enter image description here

根据Apple的文档,UINavigationController不应该是子类,因此我无法创建委托并传递数据。

问题:

  • 如何将数据从AAA传递到CCC?
  • 要做到这一点的任何工作吗?

3 个答案:

答案 0 :(得分:9)

如果您有指向导航控制器的指针,则可以获取其viewControllers数组。在该数组中,objectAtIndex:0将为CCC。

答案 1 :(得分:4)

对于任何不清楚如何实现已接受答案的人,这里有一个代码示例,可以更清楚地解释如何“have a pointer to the navigation controller”。以下代码将来自AAA(AAAViewController)的NSString传递给CCC(CCCViewController),并为segue提供名为“ToCCC”的标识符。

1)在foo中创建指向CCCViewController.h的指针。

//  CCCViewController.h

#import <UIKit/UIKit.h>

@interface CCCViewController : UITableViewController

@property (strong, nonatomic) NSString *foo;

@end

2)在AAAViewController.m中,创建一个指向CCCViewController的指针(通过导航控制器),然后设置foo

//  AAAViewController.m

#import "AAAViewController.h"
#import "CCCViewController.h" // Note the import statement for CCC.

@implementation AAAViewController

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString: @"ToCCC"])
    {
        CCCViewController *ccc = [[segue.destinationViewController viewControllers] objectAtIndex: 0];
        ccc.foo = @"A string passed from AAA";
    }
}

@end

3)在foo中对CCCViewController.m执行某些操作(例如,将其记录到控制台)。

//  CCCViewController.m

#import "CCCViewController.h"

@implementation CCCViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Log foo to the console.
    NSLog(@"%@", _foo);
}

@end

答案 2 :(得分:0)

一个不错的解决方案是在UIStoryboardSeque上创建一个类别

UIStoryboardSegue + TopLevel.h

@interface UIStoryboardSegue (TopLevel)

@property (readonly) id topLevelDestinationViewController;

@end

UIStoryboardSegue + TopLevel.m

@implementation UIStoryboardSegue (TopLevel)

- (id)topLevelDestinationViewController
{
    id dest = self.destinationViewController;
    if ([dest isKindOfClass:[UINavigationController class]]) {
        UINavigationController* nav = dest;
        dest = nav.topViewController;
    }
    return dest;
}

@end

然后使用类别

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    [super prepareForSegue:segue sender:sender];

     if ([[segue topLevelDestinationViewController] respondsToSelector:@selector(setSomeProperty:)]) 
     {
        [[segue topLevelDestinationViewController] performSelector:@selector(setSomeProperty:) withObject:self.someProperty];
     }
}

这样你的代码就会变得非常通用,而且segue的目标视图控制器是否是导航控制器并不重要