Как передать значение между NavigationController и ViewController с помощью StoryBoard?

У меня проблема,
Следующее - это StoryBoard,
первый контроллер - TabBarController,
и это отношение с A (ViewController).

How can I pass value between NavigationController and ViewController with StoryBoard?
A - это ViewController,
B - это NavigationController, смена страницы B на modal segue
C является ViewController, C изменится на другую страницу на push, поэтому мне нужен NavigationController

Хорошо, я хочу передать значение от A до C,
теперь я могу передать значение от A до B на prepareForSegue,
Однако, поскольку у B и C есть отношения, но не segue,
Поэтому я не могу передать значение от B до C на prepareForSegue!!!

Как передать значение между NavigationController и ViewController с помощью StoryBoard?

Ответы

Ответ 1

Изображение раскадровки здесь немного вводит в заблуждение.

Когда вы переходите к B, на самом деле вы переходите на комбо B/C, так как NavControllers всегда имеют по крайней мере один viewController в своем стеке (это их topViewController и их [viewControllers objectAtIndex:0]).

Итак, у вас есть отношения непосредственно от A до C.

Как вы получаете доступ к этому контроллеру, зависит от того, является ли ваш segue модальным или нажмите. В вашем случае это модально, но я опишу оба, чтобы вы могли видеть разницу.

В любом случае, чтобы передать данные на C, вам нужно объявить свойство в его заголовочном файле

    @interface CviewController: UIViewContrller
    @property (assign) int dataFromA;
    @end

push segue

В режиме push segue на самом деле это C, который является destinationViewController, а не B. Фактически, push-сегмент управляется с помощью B, который является UINavigationController для A и C. Код, лежащий в основе push-сегмента, имеет форму
[self.navigationController pushViewController:otherViewController];

В AviewController prepareForSegue:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
        {
         CviewController* controller = segue.destinationViewController;
        [controller setDataFromA:self.data];
    }

В раскадровке можно сделать линию push segue между двумя viewControllers, которые не имеют общего UINavigationController. Однако при запуске вы получите сообщение об ошибке:

'Не удалось найти контроллер навигации для segue' pushC '. Push segues может использоваться только тогда, когда управляющий источник управляется экземпляром UINavigationController. '

За каждым хорошим нажатием кнопки находится навигационный контроллер.

modal segue

Кодом, скрывающимся за модальным Segue, является метод UIViewController
- (void)presentViewController:(UIViewController *)viewControllerToPresent

В modal segue для комбинации NavController/ViewController целевой viewController - это то, на что указывает линия segue. Если он указывает на viewController, то это будет segue.destinationController(и UINavigationController будет проигнорирован, что вы не хотите здесь); если он указывает на UINavigationController, как в этом случае, это будет destinationController. Но доступ к viewController по-прежнему несложно, так как это будет диспетчер навигации topViewController.

В AviewController prepareForSegue:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
     CviewController* controller = 
        (CviewController*)[[segue destinationViewController] topViewController];
    [controller setDataFromA:self.data];
}

Обратите внимание, что в этом случае мы должны использовать синтаксис [[передача сообщений] в старом стиле]. Если мы используем modern.property.syntax, мы получаем ошибку компиляции. Это потому, что программа не знает тип desinationViewController и отказывается принимать topViewController как свойство неизвестного типа. Но он рад [отправить [реальные сообщения]] на неизвестный тип. Нам также необходимо (typecast *) избежать предупреждений компилятора.