Encontrei alguns casos agora em que seria conveniente encontrar o controlador de exibição "mais alto" (o responsável pela exibição atual), mas não encontrei uma maneira de fazê-lo.
Basicamente, o desafio é este: dado que alguém está executando em uma classe que não é um controlador de exibição (ou uma exibição) [e não tem o endereço de uma exibição ativa] e não recebeu o endereço do controlador de exibição superior ( ou, digamos, o endereço do controlador de navegação), é possível encontrar esse controlador de exibição? (E, se sim, como?)
Ou, na sua falta, é possível encontrar a vista superior?
ios
objective-c
uiview
uiviewcontroller
uikit
Hot Licks
fonte
fonte
Respostas:
O iOS 4 introduziu a propriedade rootViewController na UIWindow:
Você precisará configurá-lo depois de criar o controlador de exibição.
fonte
-[UINavigationController topViewController]
). Depois, há a palavra “raiz”, que é a raiz da árvore (como-[UIWindow rootViewController]
.Eu acho que você precisa de uma combinação da resposta aceita e do @ fishstix
Swift 3.0+
fonte
UINavigationController
e solicitar o seu,topViewController
ou mesmo verificarUITabBarController
e solicitarselectedViewController
. Isso fornecerá o controlador de visualização atualmente visível ao usuário.Para concluir a resposta do JonasG (que deixou de fora os controladores de barra de guias enquanto atravessava), aqui está minha versão do retorno do controlador de visualização atualmente visível:
fonte
childViewControllers
Uma versão não recursiva completa, cuidando de diferentes cenários:
UINavigationController
UITabBarController
Objetivo-C
Swift 4+
fonte
visibleViewController
para deixar claro o que faz.Obtendo o maior controle de visualização do Swift usando extensões
Código:
Uso:
fonte
Para concluir a resposta de Eric (que excluiu popovers, controladores de navegação, controladores de barra de guias e controladores de exibição adicionados como subvisões a alguns outros controladores de exibição durante a navegação), aqui está minha versão do retorno do controlador de exibição atualmente visível:
==================================================== ===================
==================================================== ===================
E agora tudo o que você precisa fazer para obter o maior controle de visualização é chamar o método acima, da seguinte maneira:
fonte
Esta resposta inclui
childViewControllers
e mantém uma implementação limpa e legível.fonte
Recentemente, peguei essa situação em um projeto, que exigia exibir uma visualização de notificação, independentemente do controlador exibido e do tipo (UINavigationController, controlador clássico ou controlador de exibição personalizado), quando o status da rede era alterado.
Então, acabei de liberar meu código, que é bastante fácil e, na verdade, baseado em um protocolo, para que seja flexível com todos os tipos de controladores de contêiner. Parece estar relacionado com as últimas respostas, mas de uma maneira muito flexível.
Você pode pegar o código aqui: PPTopMostController
E obteve o melhor controle usando
fonte
Esta é uma melhoria na resposta de Eric:
_topMostController(UIViewController *cont)
é uma função auxiliar.Agora tudo o que você precisa fazer é ligar
topMostController()
e o UIViewController superior deve ser retornado!fonte
self
deve pertencer.Aqui está a minha opinião sobre isso. Obrigado a @Stakenborg por apontar o caminho para pular a obtenção do UIAlertView como o principal controlador
fonte
getSomething:
em Objective-C. Isso tem um significado especial (mais: cocoadevcentral.com/articles/000082.php ) e você não atende a esses requisitos no seu código.fonte
fonte
Para a versão Swift mais recente:
Crie um arquivo, nomeie-o
UIWindowExtension.swift
e cole o seguinte trecho:Use-o em qualquer lugar como:
fonte
switch
vez de se mais. 3. não tendo certeza de que você também precisa de uma função estática, acho que você poderia fazer isso facilmente no primeiro nível de instância var que você declarou. 4. Provavelmente, é melhor não criar muitas funções globais, mas isso é uma questão de gosto. Você pode usar uma linha de código para conseguir o efeito da função global:UIApplication.sharedApplication().delegate?.window?.visibleViewController
Extensão simples para
UIApplication
no Swift:NOTA:
Ele se importa com
moreNavigationController
dentroUITabBarController
Uso simples:
fonte
Use a extensão abaixo para pegar a corrente visível
UIViewController
. Trabalhou para o Swift 4.0 e posteriorSwift 4.0 e posterior:
Como usar?
fonte
presentedViewController
primeiro, antes dos casosUINavigationController
eUITabBarController
? Caso contrário, se um controlador de exibição for apresentado modalmente a partir deUINavigationController
ouUITabBarController
, ele não será retornado como o controlador de exibição superior, mesmo que seja o controlador de exibição visível.Mais uma solução Swift
fonte
Extensão Swift 4.2
Use-o de qualquer lugar como,
ou como
Ajuste a qualquer classe como UINavigationController, UITabBarController
Aproveitar!
fonte
Aqui está o que funcionou para mim.
Descobri que, às vezes, o controlador estava nulo na janela da chave, pois a keyWindow é algo do sistema operacional como um alerta, etc.
fonte
Expandindo a resposta de @ Eric, você precisa ter cuidado para que a keyWindow seja realmente a janela que você deseja. Se você estiver tentando utilizar esse método depois de tocar em algo em uma exibição de alerta, por exemplo, a keyWindow será realmente a janela do alerta, o que causará problemas para você, sem dúvida. Isso aconteceu comigo na natureza ao lidar com links diretos por meio de um alerta e causar SIGABRTs com NO STACK TRACE. Cadela total para depuração.
Aqui está o código que estou usando agora:
Sinta-se à vontade para misturar isso com qualquer sabor de recuperação do controlador da vista superior que você gosta das outras respostas desta pergunta.
fonte
Solução Swift alternativa:
fonte
Esta solução é a mais completa. Ele leva em consideração: UINavigationController UIPageViewController UITabBarController E o controlador de exibição mais apresentado do controlador de exibição superior
O exemplo está no Swift 3.
Existem 3 sobrecargas
fonte
Uma solução concisa, porém abrangente, no Swift 4.2, leva em consideração UINavigationControllers , UITabBarControllers , controladores apresentados e filhos :
Uso:
fonte
Ótima solução no Swift, implemente no AppDelegate
fonte
Acho que a maioria das respostas foi completamente ignorada
UINavigationViewController
, então lidei com esse caso de uso com a implementação a seguir.fonte
Eu sei que é muito tarde e pode ser redundante. Mas a seguir está o trecho que eu criei e que está funcionando para mim:
fonte
Isso funciona muito bem para encontrar o viewController superior 1 a partir de qualquer controle de visualização raiz
fonte
Não tenho certeza se isso ajudará o que você está tentando realizar ao encontrar o controlador de exibição mais alto, mas eu estava tentando apresentar um novo controlador de exibição, mas se meu controlador de exibição raiz já tivesse um diálogo modal, ele seria bloqueado. passaria para o topo de todos os controladores de exibição modal usando este código:
fonte
você pode encontrar o controlador mais visualizado usando
fonte
self
não temnavigationController
propriedade.Outra solução depende da cadeia de respostas, que pode ou não funcionar, dependendo do que é a primeira resposta:
Exemplo de pseudo-código:
fonte
Rápido:
Uso:
fonte