Я собираюсь создать приложение, используя UINavigationController
для представления следующих контроллеров представления. В iOS5 появился новый метод представления UIViewControllers
:
presentViewController:animated:completion:
Теперь я спрашиваю себя, почему нет обработчика завершения UINavigationController
? Есть только
pushViewController:animated:
Можно ли создать свой собственный обработчик завершения, как новый presentViewController:animated:completion:
?
viewDidAppear:animated:
позвольте вам выполнять код каждый раз, когда ваш контроллер представления появляется на экране (viewDidLoad
только при первой загрузке вашего контроллера представления)-(void)viewDidAppear:(BOOL)animated
Ответы:
См . Ответ par для получения еще одного и более современного решения
UINavigationController
анимации запускаются сCoreAnimation
, поэтому было бы разумно инкапсулировать код внутриCATransaction
и, таким образом, установить блок завершения.Swift :
Для быстрого предлагаю создать расширение как таковое
Использование:
Objective-C
Заголовок:
Реализация:
источник
pushViewController:animated:
илиpopViewController:animated
, тоviewDidLoad
иviewDidAppear
вызовы происходят в последующих циклах runloop. Итак, у меня сложилось впечатление, что даже если эти методы вызывают анимацию, они не будут частью транзакции, представленной в примере кода. Это вас беспокоило? Потому что это решение сказочно простое.didShowViewController
Тем не менее, это гарантированно, чем показан рассматриваемый контроллер представления . Хотя это решение фантастически просто, я бы поставил под сомнение его «надежность в будущем». Особенно с учетом изменений в просмотре обратных вызовов жизненного цикла, которые появились с ios7 / 8iOS 7+ Swift
Swift 4:
РЕДАКТИРОВАТЬ: я добавил версию своего исходного ответа Swift 3. В этой версии я удалил пример совместной анимации, показанный в версии Swift 2, поскольку, похоже, это сбило с толку многих людей.
Swift 3:
Swift 2:
источник
nil
как блок анимации.nil
тоже можно.transitionCoordinator
ноль?transitionCoordinator
то, вероятно, вы вызываете эту функцию слишком рано в жизненном цикле контроллера навигации. Подождите, по крайней мере, пока неviewWillAppear()
будет вызван, прежде чем пытаться нажать на контроллер представления с анимацией.На основе ответа par (который был единственным, который работал с iOS9), но проще и с отсутствующим else (что могло привести к тому, что завершение никогда не было вызвано):
источник
В настоящее время
UINavigationController
это не поддерживается. Но есть то,UINavigationControllerDelegate
что можно использовать.Легкий способ добиться этого -
UINavigationController
создать подкласс и добавить свойство блока завершения:Перед тем, как нажать новый контроллер представления, вам нужно будет установить блок завершения:
Этот новый подкласс может быть назначен в Interface Builder или использоваться программно следующим образом:
источник
pushViewController:animated:completion:
, сделает это элегантным решением.Вот версия Swift 4 с Pop.
На всякий случай это понадобится кому-то другому.
источник
Чтобы расширить ответ @Klaas (и в результате этого вопроса), я добавил блоки завершения непосредственно в метод push:
Используется следующим образом:
источник
if... (self.pushedVC == viewController) {
это неверно. Вам нужно проверить равенство между объектами, используяisEqual:
, например,[self.pushedVC isEqual:viewController]
isEqual
вероятно , было бы более технически правильным, если бы они когда-либо сделали.Начиная с iOS 7.0, вы можете использовать
UIViewControllerTransitionCoordinator
для добавления блока завершения push:источник
Swift 2.0
источник
Чтобы добавить это поведение и сохранить возможность установки внешнего делегата, потребуется немного больше конвейеров.
Вот документированная реализация, которая поддерживает функции делегирования:
LBXCompletingNavigationController
источник