Передача данных через дочерние контроллеры навигации - PullRequest
7 голосов
/ 23 марта 2012

Обзор

У меня есть проект iOS, который содержит 2 контроллера навигации, как показано на рисунке ниже.

Я хотел бы передать некоторые данные при переходе от AAA к CCC, но между AAA и CCC имеется навигационный контроллер.

enter image description here

Согласно документации AppleUINavigationController не должен быть разделен на подклассы, поэтому я не могу создать делегат и передать данные.

Вопрос:

  • как я могу передавать данные из AAA в CCC?
  • есть ли какие-либо способы решения этой проблемы?

Ответы [ 3 ]

9 голосов
/ 23 марта 2012

Если у вас есть указатель на контроллер навигации, вы можете получить его массив viewControllers. В этом массиве objectAtIndex: 0 будет CCC.

4 голосов
/ 28 августа 2013

Для тех, кто не знает, как реализовать принятый ответ, ниже приведен пример кода, который более четко объясняет, как « имеет указатель на контроллер навигации » Следующий код передает строку NSString из AAA (AAAViewController) в CCC (CCCViewController) с идентификатором «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
0 голосов
/ 13 ноября 2012

Хорошим решением является создание категории на 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 контроллером навигации или нет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...