Как я могу передать значение между NavigationController и ViewController с раскадровкой?

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

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

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

Как я могу передать значение между NavigationController и ViewController с раскадровкой?

1 ответов


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

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

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

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

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

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

нажмите segue

в push-сегменте фактически C является destinationViewController, а не B. На самом деле push-сегмент управляется B, который является UINavigationController как для A, так и для C. Код за push-сегментом имеет форма
[self.navigationController pushViewController:otherViewController];

в prepareForSegue AviewController:

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

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

'не удалось найти навигационный контроллер для segue 'pushC'. Push-сегменты могут использоваться только тогда, когда исходный контроллер управляется экземпляр UINavigationController.'

за каждым хорошим толчком segue лежит навигационный контроллер.

модальный переход

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

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

в prepareForSegue AviewController:

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

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