Podczas odrzucania modalnego kontrolera widoku za pomocą dismissViewController
, istnieje opcja zapewnienia bloku uzupełniania. Czy istnieje podobny odpowiednik popViewController
?
Argument ukończenia jest całkiem przydatny. Na przykład mogę go użyć do wstrzymania usuwania wiersza z widoku tabeli, dopóki modal nie zniknie z ekranu, pozwalając użytkownikowi zobaczyć animację wiersza. Wracając z wypychanego kontrolera widoku, chciałbym mieć taką samą możliwość.
Próbowałem umieścić popViewController
w UIView
bloku animacji, gdzie mam dostęp do bloku uzupełniania. Jednak powoduje to niepożądane efekty uboczne na wyskakującym widoku.
Jeśli nie ma takiej metody, jakie są obejścia?
ios
cocoa-touch
uiview
uiviewcontroller
uiviewanimation
Ben Packard
źródło
źródło
Odpowiedzi:
Wiem, że odpowiedź została przyjęta ponad dwa lata temu, jednak jest ona niepełna.
Jest to technicznie poprawne, ponieważ
UINavigationController
interfejs API nie oferuje żadnych opcji. Jednak za pomocą struktury CoreAnimation można dodać blok uzupełniania do podstawowej animacji:Blok ukończenia zostanie wywołany zaraz po zakończeniu animacji
popViewControllerAnimated:
. Ta funkcjonalność jest dostępna od iOS 4.źródło
extension UINavigationController { func popViewControllerWithHandler(handler: ()->()) { CATransaction.begin() CATransaction.setCompletionBlock(handler) self.popViewControllerAnimated(true) CATransaction.commit() } }
Dla wersji SWIFT na iOS9 - działa jak urok (nie był testowany dla wcześniejszych wersji). Na podstawie tej odpowiedzi
źródło
Zrobiłem
Swift
wersję z rozszerzeniami z odpowiedzią @JorisKluivers .Spowoduje to wywołanie zakończenia zakończenia po zakończeniu animacji dla obu
push
ipop
.źródło
popViewController
lubpushViewController
, ale jeśli zaraz potem sprawdzisz, czym jest topViewController, zauważysz, że nadal jest stary, tak jakpop
lubpush
nigdy się nie zdarzyło ...SWIFT 4.1
źródło
Miałem ten sam problem. A ponieważ musiałem go używać przy wielu okazjach iw ramach łańcuchów bloków uzupełniania, stworzyłem to ogólne rozwiązanie w podklasie UINavigationController:
Zarozumiały
i
i
źródło
Nie ma sposobu, aby zrobić to, czego chcesz, po wyjęciu z pudełka. tj. nie ma metody z blokiem uzupełniania do zdejmowania kontrolera widoku ze stosu nawigacji.
To, co zrobiłbym, to umieścić logikę
viewDidAppear
. Zostanie to wywołane, gdy widok skończy się pojawiać na ekranie. Będzie wywoływany dla wszystkich różnych scenariuszy pojawiania się kontrolera widoku, ale to powinno wystarczyć.Lub możesz użyć tej
UINavigationControllerDelegate
metody,navigationController:didShowViewController:animated:
aby zrobić podobną rzecz. Jest to wywoływane, gdy kontroler nawigacji zakończy wypychanie lub otwieranie kontrolera widoku.źródło
dismissViewController
. Może nadejdziepopViewController
. Złóż radar :-).-dismissViewController:animated:completionBlock:
, ale możesz uzyskać animację za pośrednictwem delegata kontrolera nawigacji. Po zakończeniu animacji-navigationController:didShowViewController:animated:
zostaniesz wezwany do delegata i będziesz mógł zrobić wszystko, co potrzebujesz.Praca z animacją lub bez niej, a także
popToRootViewController
:źródło
completion()
asynchronicznego?completion
nigdy nie jest wykonywana na tym samym runloopie. to gwarantuje, żecompletion
nigdy nie będzie działać na tym samym runloopie, gdy nie jest animowany. lepiej nie mieć tego rodzaju niespójności.W oparciu o odpowiedź @ HotJard, kiedy wszystko, czego potrzebujesz, to tylko kilka linii kodu. Szybko i łatwo.
Swift 4 :
źródło
Na rok 2018 ...
jeśli masz to ...
i chcesz dodać uzupełnienie ...
to takie proste.
Przydatna wskazówka ...
Ta sama sprawa dotyczy wygodnego
popToViewController
połączenia.Typową rzeczą jest to, że masz na pokładzie stos zillionów ekranów. Kiedy w końcu skończysz, wrócisz z powrotem do ekranu „podstawowego”, a następnie uruchomisz aplikację.
Na ekranie „podstawowym”, aby przejść „całą drogę wstecz”,
popToViewController(self
źródło
Blok uzupełniania jest wywoływany po wywołaniu metody viewDidDisappear na prezentowanym kontrolerze widoku, więc umieszczenie kodu w metodzie viewDidDisappear kontrolera widoku popped powinno działać tak samo jak blok uzupełniania.
źródło
Szybka 3 odpowiedź, dzięki tej odpowiedzi: https://stackoverflow.com/a/28232570/3412567
źródło
Wersja Swift 4 z opcjonalnym parametrem viewController, aby wyświetlić konkretny.
źródło
Wyczyszczono wersję Swift 4 na podstawie tej odpowiedzi .
źródło
Istnieje pod o nazwie UINavigationControllerWithCompletionBlock, który dodaje obsługę bloku uzupełniania podczas wypychania i wyskakiwania na UINavigationController.
źródło
2020 Swift 5.1 sposób
To rozwiązanie gwarantuje, że ukończenie zostanie wykonane po całkowitym zakończeniu popViewController. Możesz to przetestować, wykonując inną operację na NavigationController w zakończeniu: We wszystkich innych rozwiązaniach powyżej UINavigationController jest nadal zajęty operacją popViewController i nie odpowiada.
źródło
Dla kompletności przygotowałem kategorię Cel-C gotową do użycia:
źródło
Osiągnąłem to dokładnie z precyzją za pomocą bloku. Chciałem, aby mój kontroler pobranych wyników pokazywał wiersz dodany przez widok modalny tylko wtedy, gdy całkowicie opuścił ekran, aby użytkownik mógł zobaczyć zachodzącą zmianę. Przygotowując się do przejścia, które jest odpowiedzialne za wyświetlanie kontrolera widoku modalnego, ustawiam blok, który chcę wykonać, gdy modal zniknie. W kontrolerze widoku modalnego nadpisuję viewDidDissapear, a następnie wywołuję blok. Po prostu zaczynam aktualizacje, gdy modal ma się pojawić, i kończę aktualizacje, gdy zniknie, ale to dlatego, że używam NSFetchedResultsController, ale możesz robić, co chcesz, wewnątrz bloku.
źródło
Użyj następnego rozszerzenia w swoim kodzie: (Swift 4)
źródło