Ao descartar um controlador de visualização modal usando dismissViewController
, há a opção de fornecer um bloco de conclusão. Existe um equivalente semelhante para popViewController
?
O argumento de conclusão é bastante útil. Por exemplo, posso usá-lo para evitar a remoção de uma linha de um tableview até que o modal esteja fora da tela, permitindo que o usuário veja a animação da linha. Ao retornar de um controlador de visualização empurrado, gostaria da mesma oportunidade.
Tentei colocar popViewController
em um UIView
bloco de animação, onde tenho acesso a um bloco de conclusão. No entanto, isso produz alguns efeitos colaterais indesejados na exibição para a qual o pop-up está sendo exibido.
Se esse método não estiver disponível, quais são algumas soluções alternativas?
fonte
Respostas:
Sei que uma resposta foi aceita há mais de dois anos, mas essa resposta está incompleta.
Isso é tecnicamente correto porque a
UINavigationController
API não oferece opções para isso. No entanto, usando a estrutura CoreAnimation, é possível adicionar um bloco de conclusão à animação subjacente:O bloco de conclusão será chamado assim que a animação usada por
popViewControllerAnimated:
terminar. Esta funcionalidade está disponível desde o iOS 4.fonte
extension UINavigationController { func popViewControllerWithHandler(handler: ()->()) { CATransaction.begin() CATransaction.setCompletionBlock(handler) self.popViewControllerAnimated(true) CATransaction.commit() } }
Para a versão iOS9 SWIFT - funciona perfeitamente (não tinha testado para versões anteriores). Com base nesta resposta
fonte
Fiz uma
Swift
versão com extensões com a resposta @JorisKluivers .Isso chamará um fechamento de conclusão após a animação ser feita para
push
epop
.fonte
popViewController
oupushViewController
, mas se você verificar o que o topViewController é logo depois, você notará que ainda é o antigo, assim comopop
oupush
nunca aconteceu ...SWIFT 4.1
fonte
Eu tive o mesmo problema. E como tive que usá-lo em várias ocasiões e dentro de cadeias de blocos de conclusão, criei esta solução genérica em uma subclasse UINavigationController:
Assumindo
e
e
fonte
Não há como fazer o que você quer fora da caixa. ou seja, não existe nenhum método com um bloco de conclusão para retirar um controlador de visualização de uma pilha de navegação.
O que eu faria é colocar a lógica
viewDidAppear
. Isso será chamado quando a visualização terminar de aparecer na tela. Ele será chamado para todos os diferentes cenários de exibição do controlador de visualização, mas isso deve funcionar.Ou você pode usar o
UINavigationControllerDelegate
métodonavigationController:didShowViewController:animated:
para fazer algo semelhante. Isso é chamado quando o controlador de navegação termina de empurrar ou abrir um controlador de visualização.fonte
dismissViewController
. Talvez aconteçapopViewController
. Arquive um radar :-).-dismissViewController:animated:completionBlock:
, pode obter a animação por meio do delegado do controlador de navegação. Depois de concluída a animação,-navigationController:didShowViewController:animated:
será chamado o delegado e você poderá fazer o que precisar ali mesmo.Trabalhar com ou sem animação adequadamente e também inclui
popToRootViewController
:fonte
completion()
assíncrono?completion
nunca é executado no mesmo runloop. isso garantecompletion
nunca ser executado no mesmo runloop quando não estiver em animação. é melhor não ter esse tipo de inconsistência.Com base na resposta de @ HotJard, quando tudo o que você deseja são apenas algumas linhas de código. Rápido e fácil.
Swift 4 :
fonte
Para 2018 ...
se você tem isso ...
e você deseja adicionar uma conclusão ...
é simples assim.
Dica útil ...
É a mesma coisa para uma
popToViewController
chamada acessível .Uma coisa típica é você ter uma pilha integrada de um zilhão de telas. Quando finalmente terminar, você volta à sua tela "base" e, finalmente, inicia o aplicativo.
Então, na tela "base", para ir "todo o caminho de volta",
popToViewController(self
fonte
O bloco de conclusão é chamado depois que o método viewDidDisappear é chamado no controlador de exibição apresentado, portanto, colocar o código no método viewDidDisappear do controlador de exibição exibido deve funcionar da mesma forma que um bloco de conclusão.
fonte
Resposta do Swift 3, graças a esta resposta: https://stackoverflow.com/a/28232570/3412567
fonte
Versão do Swift 4 com parâmetro opcional viewController para acessar um específico.
fonte
Limpei a versão do Swift 4 com base nesta resposta .
fonte
Há um pod chamado UINavigationControllerWithCompletionBlock que adiciona suporte para um bloco de conclusão ao enviar e enviar um UINavigationController.
fonte
2020 Swift 5.1 way
Esta solução garante que a conclusão seja executada depois que popViewController estiver totalmente concluído. Você pode testá-lo executando outra operação no NavigationController na conclusão: Em todas as outras soluções acima, o UINavigationController ainda está ocupado com a operação popViewController e não responde.
fonte
Apenas para completar, preparei uma categoria Objective-C para usar:
fonte
Consegui exatamente isso com precisão usando um bloco. Eu queria que meu controlador de resultados buscados mostrasse a linha que foi adicionada pela visualização modal, apenas depois de ter saído totalmente da tela, para que o usuário pudesse ver a mudança acontecendo. Em preparação para segue, que é responsável por mostrar o controlador de visualização modal, eu defino o bloco que desejo executar quando o modal desaparecer. E no controlador de visualização modal eu substituo viewDidDissapear e chamo o bloco. Simplesmente começo as atualizações quando o modal vai aparecer e as termino quando ele desaparece, mas isso é porque estou usando um NSFetchedResultsController, entretanto, você pode fazer o que quiser dentro do bloco.
fonte
Use a próxima extensão em seu código: (Swift 4)
fonte