Как связать контроллеры просмотра в раскадровке xcode?

Я хотел бы связать контроллеры представления в раскадровке xcode для достижения следующего эффекта:

A -> B -> C -> D -> E -> B -> C -> D -> E -> B -> ...

где приведенные выше буквы обозначают отдельные контроллеры представления (полноразмерные сцены). Я хочу иметь горизонтальный переход слайда справа налево при переходе между представлениями, и я не хочу или не нуждаюсь в сохранении состояния для предыдущих представлений (т.е. без толчка или модального перехода). Однако мне нужно передать некоторое состояние между представлениями.

Любые предложения о том, как лучше всего добиться этого, используя редактор раскадровки, код или их комбинацию?


person philipfc    schedule 22.01.2013    source источник


Ответы (1)


Пара вариантов бросается в глаза:

  1. Самое простое решение с наибольшей обратной совместимостью со старыми версиями iOS — это использовать контроллер навигации, где-то хранить ссылку на контроллер представления B, а затем вы можете в E иметь некоторый IBAction, который делает:

    [self.navigationController popToViewController:B animated:YES];
    

    В этой модели все переходы будут представлены в раскадровке, кроме одного от E до B, для которого вы должны использовать приведенный выше код в IBAction (или любом другом).

  2. Если вы можете отказаться от совместимости с iOS 5, вы также можете использовать переход unwind. В этом сценарии все переходы будут представлены в раскадровке. Но многие из нас пока не готовы отказываться от совместимости с iOS 5, поэтому, возможно, вам не стоит рассматривать это решение. Но если бы вы действительно хотели использовать переход отката, вы бы просто определили действие отмотки в B, например:

    - (IBAction)backToB:(UIStoryboardSegue *)segue
    {
        // if you need to do any UI update because we got an unwind segue
        // back to this controller, do that here
    }
    

    Как только вы выполните это действие раскрутки в B, у вас внезапно появится новый тип перехода под названием backToB (хотя я бы посоветовал вам дать ему имя получше), представленный вам в IB, и вы можете использовать его для перехода от с E по B. Очевидно, что все остальные переходы будут представлены в вашей раскадровке как обычно.

  3. Если вы действительно не хотите использовать навигационный контроллер, но вам не нужна совместимость с iOS 4, вы также можете добиться этого с помощью сдерживания контроллера представления, где у вас есть родительский настраиваемый контейнерный контроллер, ParentVC, а от A до E будут дочерними. контроллеры. Затем у вас могут быть пользовательские переходы для перехода через последовательность дочерних контроллеров.

  4. Одним из последних вариантов может быть следующее:

    BABCDE

    В этом сценарии, как и в варианте 1, вы просто используете навигационный контроллер, когда B загружается впервые, он программно немедленно делает следующее в viewDidLoad

    [self presentViewController:A animated:NO];
    

    Хотя B является корневым контроллером представления, похоже, что A им был. Когда A будет выполнено, он вернется к B, и в этот момент вы сможете выполнить стандартный переход B-C-D-E push segue, но поскольку мы сделали B корневым контроллером, E может просто выполнить popToRootViewControllerAnimated, чтобы вернуться к B, и вам не нужно беспокоиться о сохранении указателя на B. Эта модель имеет большой смысл, если A является контроллером входа в систему или экраном-заставкой, или чем-то несколько выходящим за рамки обычного потока.

Из них 1, вероятно, самый простой, 2 может считаться самым элегантным (хотя вы потеряете поддержку iOS 5 и более ранних версий), 3 — вариант, если вы не против написать немного больше (кто-то сложный) код, а использование памяти имеет решающее значение. , и 4, как и 1, довольно просто, но вопрос лишь в том, подходит ли поток для вашего приложения. Лично я склоняюсь к варианту 1 или 4, в зависимости от того, какой контроллер представления A был. И если потребуется совместимость с iOS 4, эти два варианта будут работать и с NIB.

person Rob    schedule 22.01.2013
comment
Вариант 4 выглядит хорошо, за исключением навигации вверху. Используя свойства или код, есть ли простой способ скрыть навигацию, которую навигационный контроллер вводит в верхней части каждого последующего представления? - person philipfc; 23.01.2013
comment
@philipfc В коде: [self.navigationController setNavigationBarHidden:YES animated:NO]; в B viewDidLoad. Вы также можете перейти к раскадровке, щелкнуть навигационный контроллер, перейти к инспектору атрибутов (четвертая вкладка на самой правой панели), перейти к смоделированным показателям и отключить верхнюю панель. Это не заменяет код setNavigationBarHidden, а просто упрощает разработку ваших сцен, если вы знаете, как они будут выглядеть на самом деле. И если вы сделаете это на самом навигационном контроллере, эта смоделированная метрика будет распространяться на все сцены. - person Rob; 23.01.2013
comment
Это хорошо сочетается. Единственное изменение, которое я внес во время тестирования, — снять флажок «Показывать панель навигации» в инспекторе атрибутов навигационного контроллера, и это, похоже, устраняет необходимость скрывать панель навигации в коде. - person philipfc; 23.01.2013
comment
@philipfc Я не знал об этом варианте, но это имеет смысл. Спасибо! - person Rob; 23.01.2013