При отказе от использования контроллера модального представления dismissViewController
есть возможность предоставить блок завершения. Есть ли аналогичный для popViewController
?
Аргумент завершения очень удобен. Например, я могу использовать его, чтобы отложить удаление строки из представления таблицы до тех пор, пока модальное окно не выключится, позволяя пользователю увидеть анимацию строки. Когда я возвращаюсь из выталкиваемого контроллера представления, мне нужна такая же возможность.
Я попытался разместить popViewController
в UIView
блоке анимации, где у меня есть доступ к блоку завершения. Однако это приводит к нежелательным побочным эффектам в отображаемом представлении.
Если такого метода нет, каковы обходные пути?
ios
cocoa-touch
uiview
uiviewcontroller
uiviewanimation
Бен Паккард
источник
источник
Ответы:
Я знаю, что ответ был принят более двух лет назад, однако это неполный ответ.
Это технически правильно, потому что
UINavigationController
API не предлагает для этого никаких вариантов. Однако с помощью структуры CoreAnimation можно добавить блок завершения к базовой анимации:Блок завершения будет вызван, как только анимация, используемая пользователем,
popViewControllerAnimated:
закончится. Эта функция доступна с iOS 4.источник
extension UINavigationController { func popViewControllerWithHandler(handler: ()->()) { CATransaction.begin() CATransaction.setCompletionBlock(handler) self.popViewControllerAnimated(true) CATransaction.commit() } }
Для версии iOS9 SWIFT - работает как шарм (для более ранних версий не тестировался). На основании этого ответа
источник
Я сделал
Swift
версию с расширениями с ответом @JorisKluivers .Это вызовет завершение закрытия после того, как анимация будет выполнена для обоих
push
иpop
.источник
popViewController
orpushViewController
, но если вы проверите, что такое topViewController сразу после этого, вы заметите, что он все еще старый, точно так же, какpop
илиpush
никогда не было ...SWIFT 4.1
источник
Я была такая же проблема. И поскольку мне приходилось использовать его несколько раз и в цепочках блоков завершения, я создал это универсальное решение в подклассе UINavigationController:
Если предположить,
и
и
источник
Нет возможности делать то, что вы хотите, из коробки. то есть не существует метода с блоком завершения для извлечения контроллера представления из стека навигации.
Я бы добавил логику
viewDidAppear
. Это будет вызвано, когда представление перестанет отображаться на экране. Он будет вызываться для всех различных сценариев появления контроллера представления, но это должно быть нормально.Или вы можете использовать этот
UINavigationControllerDelegate
метод,navigationController:didShowViewController:animated:
чтобы сделать то же самое. Это вызывается, когда контроллер навигации завершает нажатие или выталкивание контроллера представления.источник
dismissViewController
. Может, до этого дойдетpopViewController
. Подать радар :-).-dismissViewController:animated:completionBlock:
, но вы можете получить анимацию через делегата контроллера навигации. После завершения анимации-navigationController:didShowViewController:animated:
будет вызван делегат, и вы сможете делать все, что вам нужно, прямо сейчас.Правильная работа с анимацией или без нее, а также включает
popToRootViewController
:источник
completion()
асинхронный режим ?completion
никогда не выполняется в одном цикле выполнения. это гарантирует, чтоcompletion
никогда не будет запущен один и тот же цикл выполнения без анимации. Лучше не допускать такой непоследовательности.На основе ответа @ HotJard, когда все, что вам нужно, это всего лишь пара строк кода. Быстро и просто.
Swift 4 :
источник
На 2018 год ...
если у тебя есть это ...
и вы хотите добавить доработку ...
это так просто.
Подсказка ...
То же самое и для удобных
popToViewController
звонка.Как правило, у вас есть стэк из миллиарда экранов. Когда, наконец, закончите, вы полностью вернетесь к своему «базовому» экрану, а затем, наконец, запустите приложение.
Итак, на «базовом» экране, чтобы вернуться «полностью назад»,
popToViewController(self
источник
Блок завершения вызывается после вызова метода viewDidDisappear в представленном контроллере представления, поэтому размещение кода в методе viewDidDisappear контроллера всплывающего представления должно работать так же, как блок завершения.
источник
Ответ Swift 3, благодаря этому ответу: https://stackoverflow.com/a/28232570/3412567
источник
Версия Swift 4 с необязательным параметром viewController для перехода к конкретному.
источник
На основе этого ответа исправлена версия Swift 4 .
источник
Существует модуль под названием UINavigationControllerWithCompletionBlock, который добавляет поддержку блока завершения при нажатии и извлечении UINavigationController.
источник
2020 Swift 5.1 способ
Это решение гарантирует, что завершение будет выполнено после полного завершения popViewController. Вы можете проверить это, выполнив еще одну операцию в NavigationController в завершении: во всех других решениях выше UINavigationController все еще занят операцией popViewController и не отвечает.
источник
Для полноты картины я подготовил категорию Objective-C:
источник
Я добился именно этого с точностью с помощью блока. Я хотел, чтобы мой полученный контроллер результатов отображал строку, добавленную модальным представлением, только после того, как она полностью покинула экран, чтобы пользователь мог видеть происходящие изменения. При подготовке к переходу, который отвечает за отображение контроллера модального представления, я устанавливаю блок, который хочу выполнить, когда модальное окно исчезнет. И в контроллере модального представления я переопределяю viewDidDissapear, а затем вызываю блок. Я просто начинаю обновления, когда появится модальное окно, и заканчиваю обновления, когда он исчезает, но это потому, что я использую NSFetchedResultsController, однако внутри блока вы можете делать все, что захотите.
источник
Используйте следующее расширение в своем коде: (Swift 4)
источник