Eu segui este tópico para substituir -preferredStatusBarStyle
, mas não é chamado. Existem opções que eu posso alterar para habilitá-lo? (Estou usando XIBs no meu projeto.)
ios
ios7
uikit
uistatusbar
trgoofi
fonte
fonte
Respostas:
Possível causa raiz
Eu tinha o mesmo problema e descobri que estava acontecendo porque não estava configurando o controlador de exibição raiz na janela do meu aplicativo.
O
UIViewController
em que eu havia implementado opreferredStatusBarStyle
foi usado em umUITabBarController
, que controlava a aparência das visualizações na tela.Quando defino o controlador de exibição raiz para apontar para isso
UITabBarController
, as alterações da barra de status começaram a funcionar corretamente, conforme o esperado (e opreferredStatusBarStyle
método estava sendo chamado).Método alternativo (descontinuado no iOS 9)
Como alternativa, você pode chamar um dos seguintes métodos, conforme apropriado, em cada um dos controladores de exibição, dependendo da cor de fundo, em vez de precisar usar
setNeedsStatusBarAppearanceUpdate
:ou
Note que você também precisará conjunto
UIViewControllerBasedStatusBarAppearance
paraNO
no arquivo plist se você usar este método.fonte
setNeedsStatusBarAppearanceUpdate
- minhas suspeitas foram confirmadas quando fiz essa alteração.Para quem usa um UINavigationController:
O
UINavigationController
não encaminha aspreferredStatusBarStyle
chamadas para seus controladores de exibição filho. Em vez disso, ele gerencia seu próprio estado - como deveria, está desenhando na parte superior da tela onde fica a barra de status e, portanto, deve ser responsável por ela. A implementaçãopreferredStatusBarStyle
em seus VCs dentro de um controlador nav não fará nada - eles nunca serão chamados.O truque é quais são os
UINavigationController
usos para decidir para o que retornarUIStatusBarStyleDefault
ouUIStatusBarStyleLightContent
. Ele baseia isso no seuUINavigationBar.barStyle
. O padrão (UIBarStyleDefault
) resulta naUIStatusBarStyleDefault
barra de status escura do primeiro plano . EUIBarStyleBlack
dará umaUIStatusBarStyleLightContent
barra de status.TL; DR:
Se você quiser
UIStatusBarStyleLightContent
em umUINavigationController
uso:fonte
preferredStatusBarStyle
, de fato, será chamado no controlador de exibição filho se você ocultar a barra de navegação (definidanavigationBarHidden
comoYES
), exatamente como apropriado.[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHidden
conjunto comoYES
realmentepreferredStatusBarStyle
ligou e um aviso para aqueles que podem tropeçar nisso: funciona comnavigationBarHidden
, mas não comnavigationBar.hidden
!Então, na verdade, adicionei uma categoria ao UINavigationController, mas usei os métodos:
e eles devolveram o atual UIViewController visível. Isso permite que o atual controlador de exibição visível defina seu próprio estilo / visibilidade preferido.
Aqui está um trecho de código completo para ele:
Em Swift:
No Objetivo-C:
E, para uma boa medida, veja como é implementado em um UIViewController:
Na Swift
No Objetivo-C
Finalmente, verifique se o plist aplicativo que não têm a "visão baseada em controlador de barra de status aparência" conjunto de NO. Exclua essa linha ou defina-a como SIM (que acredito ser o padrão agora para o iOS 7?)
fonte
return self.topViewController;
funciona para mim, masreturn self.visibleViewController;
- nãosuper
esse método e realmente deseja alterar o comportamento de todos os controladores desse tipoPara quem ainda está lutando com isso, esta simples extensão rápida deve resolver o problema para você.
fonte
Meu aplicativo utilizado todos os três:
UINavigationController
,UISplitViewController
,UITabBarController
,, assim, todos estes parecem assumir o controle sobre a barra de status e fará com quepreferedStatusBarStyle
a não ser chamado para os seus filhos. Para substituir esse comportamento, você pode criar uma extensão como as demais respostas mencionadas. Aqui está uma extensão para todos os três, no Swift 4. A Wish Apple foi mais clara sobre esse tipo de coisa.Edit: Atualização para mudanças na API do Swift 4.2
fonte
A resposta da Tyson está correta ao alterar a cor da barra de status para branco
UINavigationController
.Se alguém quiser obter o mesmo resultado escrevendo o código
AppDelegate
, use o código abaixo e escreva-o dentro doAppDelegate's
didFinishLaunchingWithOptions
métodoE não se esqueça de configurá
UIViewControllerBasedStatusBarAppearance
-loYES
no arquivo .plist, caso contrário a alteração não será refletida.Código
fonte
Em um UINavigationController,
preferredStatusBarStyle
não é chamado porquetopViewController
é preferívelself
. Portanto, para serpreferredStatusBarStyle
chamado em um UINavigationController, você precisa alterá-lochildViewControllerForStatusBarStyle
.Recomendação
Substitua seu UINavigationController na sua classe:
Alternativa não recomendada
Para fazer isso em todos os UINavigationController, você pode substituir em uma extensão (aviso: afeta UIDocumentPickerViewController, UIImagePickerController, etc.), mas provavelmente não deve fazê-lo de acordo com a documentação do Swift :
fonte
Além da resposta de serenn, se você estiver apresentando um controlador de exibição com um
modalPresentationStyle
(por exemplo.overCurrentContext
), também deve chamar isso no novo controlador de exibição:Não se esqueça de substituir também o
preferredStatusBarStyle
controlador de exibição apresentado.fonte
Uma adição à resposta do Hippo: se você estiver usando um UINavigationController, provavelmente será melhor adicionar uma categoria:
Essa solução é provavelmente melhor do que mudar para o comportamento que será depreciado em breve.
fonte
preferredStatusBarStyle
e executa a lógica específica do UINavigationController. No momento, essa lógica é baseada,navigationBar.barStyle
mas eu posso ver verificações adicionais sendo adicionadas (por exemplo,UISearchDisplayController
movendo para ocultar o modo barra de navegação). Ao substituir a lógica padrão, você perde toda essa funcionalidade e se abre para momentos irritantes de 'wtf' no futuro. Veja minha resposta acima para a maneira correta de fazer isso, enquanto ainda suporta o comportamento interno do controlador de navegação.Swift 4.2 e superior
Conforme mencionado na resposta selecionada , a causa raiz é verificar o objeto do controlador de visualização raiz da janela.
Casos possíveis da sua estrutura de fluxo
é um controlador de visualização raiz da janela O seu controlador de visualização raiz da janela é um objeto UIViewController e adiciona ou remove ainda o controlador de navegação ou o tabController com base no fluxo do aplicativo.
Esse tipo de fluxo geralmente é usado se o aplicativo tiver um fluxo de pré-login na pilha de navegação sem guias e postar o fluxo de login com guias e, possivelmente, todas as guias contenham o controlador de navegação.
Este é o fluxo em que o controlador de visualização raiz da janela é tabBarController, possivelmente todas as guias mantêm ainda o controlador de navegação.
Este é o fluxo em que o controlador de visualização raiz da janela é navigationController.
Não tenho certeza se existe a possibilidade de adicionar um controlador de barra de guias ou um novo controlador de navegação em um controlador de navegação existente. Mas, se houver, precisamos passar o controle de estilo da barra de status para o próximo contêiner. Então, adicionei a mesma verificação na extensão UINavigationController para encontrar
childForStatusBarStyle
Use as seguintes extensões, ele lida com todos os cenários acima -
UIViewControllerBasedStatusBarAppearance
digitarinfo.plist
como verdadeiro por padrãoPontos a considerar para fluxos mais complexos
Caso você apresente um novo fluxo de maneira modal, ele se desconecta do fluxo de estilo da barra de status existente. Portanto, suponha que você esteja apresentando um
NewFlowUIViewController
e, em seguida, inclua um novo controlador de navegação ou tabBar eNewFlowUIViewController
, em seguida, adicione extensão deNewFlowUIViewController
para gerenciar ainda mais o estilo da barra de status do controlador.Caso você defina modalPresentationStyle que
fullScreen
não seja a apresentação modal, definamodalPresentationCapturesStatusBarAppearance
como true para que o controlador de exibição apresentado receba o controle de aparência da barra de status.fonte
iOS 13 Soluções
UINavigationController
é uma subclasse deUIViewController
(quem sabia 🙃)!Portanto, ao apresentar controladores de exibição incorporados nos controladores de navegação, você realmente não está apresentando os controladores de exibição incorporados; você está apresentando os controladores de navegação!
UINavigationController
, como uma subclasse deUIViewController
, herdapreferredStatusBarStyle
echildForStatusBarStyle
, que você pode definir como desejado.Qualquer um dos seguintes métodos deve funcionar:
info.plist
, adicione a seguinte propriedade:UIUserInterfaceStyle
(também conhecida como "Estilo da interface do usuário")Substituir
preferredStatusBarStyle
dentroUINavigationController
preferredStatusBarStyle
( doc ) - O estilo preferido da barra de status para o controlador de exibiçãoSubclasse ou extensão
UINavigationController
OU
Substituir
childForStatusBarStyle
dentroUINavigationController
childForStatusBarStyle
( doc ) - Chamado quando o sistema precisa que o controlador de exibição seja usado para determinar o estilo da barra de statusSubclasse ou extensão
UINavigationController
OU
Você pode retornar qualquer controlador de exibição que desejar acima. Eu recomendo um dos seguintes:
topViewController
(ofUINavigationController
) ( doc ) - O controlador de exibição na parte superior da pilha de navegaçãovisibleViewController
(ofUINavigationController
) ( doc ) - O controlador de visualização associado à visualização atualmente visível na interface de navegação (dica: isso pode incluir "um controlador de visualização que foi apresentado modalmente em cima do próprio controlador de navegação")Nota: Se você decidir fazer uma subclasse
UINavigationController
, lembre-se de aplicar essa classe aos controladores de navegação por meio do inspetor de identidade no IB.PS Meu código usa a sintaxe do Swift 5.1 😎
fonte
A resposta de @ serenn acima ainda é excelente para o caso de UINavigationControllers. No entanto, no swift 3, as funções childViewController foram alteradas para
vars
. Portanto, oUINavigationController
código de extensão deve ser:E então no controlador de exibição que deve ditar o estilo da barra de status:
fonte
Se o seu viewController estiver em UINavigationController.
Subclasse UINavigationController e adicione
O ViewController
preferredStatusBarStyle
será chamado.fonte
UIStatusBarStyle no iOS 7
A barra de status no iOS 7 é transparente, a exibição por trás disso é mostrada.
O estilo da barra de status refere-se às aparências de seu conteúdo. No iOS 7, o conteúdo da barra de status é escuro (
UIStatusBarStyleDefault
) ou claro (UIStatusBarStyleLightContent
). AmbosUIStatusBarStyleBlackTranslucent
eUIStatusBarStyleBlackOpaque
estão obsoletos no iOS 7.0. Use emUIStatusBarStyleLightContent
vez disso.Como mudar
UIStatusBarStyle
Se abaixo da barra de status houver uma barra de navegação, o estilo da barra de status será ajustado para corresponder ao estilo da barra de navegação (
UINavigationBar.barStyle
):Especificamente, se o estilo da barra de navegação for UIBarStyleDefault, o estilo da barra de status será
UIStatusBarStyleDefault
; se o estilo da barra de navegação forUIBarStyleBlack
, o estilo da barra de status seráUIStatusBarStyleLightContent
.Se não houver barra de navegação abaixo da barra de status, o estilo da barra de status poderá ser controlado e alterado por um controlador de exibição individual enquanto o aplicativo é executado.
-
[UIViewController preferredStatusBarStyle]
é um novo método adicionado no iOS 7. Pode ser substituído para retornar o estilo preferido da barra de status:Se o estilo da barra de status deve ser controlado por um controlador de exibição filho em vez de por si próprio, substitua
-[UIViewController childViewControllerForStatusBarStyle]
para retornar esse controlador de exibição filho.Se você preferir desativar esse comportamento e definir o estilo da barra de status usando o
-[UIApplication statusBarStyle]
método, adicione aUIViewControllerBasedStatusBarAppearance
chave aoInfo.plist
arquivo de um aplicativo e atribua o valor NÃO.fonte
Se alguém estiver usando um Controlador de Navegação e desejar que todos os controladores de navegação tenham o estilo preto, você poderá escrever uma extensão para o UINavigationController como este no Swift 3 e ela será aplicada a todos os controladores de navegação (em vez de atribuí-lo a um controlador em um Tempo).
fonte
No Swift para qualquer tipo de UIViewController:
No seu
AppDelegate
conjunto:myRootController
pode ser qualquer tipo deUIViewController
, por exemplo,UITabBarController
ouUINavigationController
.Em seguida, substitua esse controlador raiz assim:
Isso mudará a aparência da barra de status em todo o aplicativo, porque o controlador raiz é o único responsável pela aparência da barra de status.
Lembre-se de definir a propriedade
View controller-based status bar appearance
como YES no seuInfo.plist
para fazer esse trabalho (que é o padrão).fonte
Solução Swift 3 iOS 10:
fonte
A maioria das respostas não inclui uma boa implementação de
childViewControllerForStatusBarStyle
método paraUINavigationController
. De acordo com minha experiência, você deve lidar com casos como quando o controlador de exibição transparente é apresentado sobre o controlador de navegação. Nesses casos, você deve passar o controle para o seu controlador modal (visibleViewController
), mas não quando estiver desaparecendo.fonte
No meu caso, apresentei acidentalmente o View / Navigation Controller como
UIModalPresentationStyle.overFullScreen
, o que faz com quepreferredStatusBarStyle
não seja chamado. Depois de voltar paraUIModalPresentationStyle.fullScreen
, tudo funciona.fonte
Quanto ao iOS 13.4, o
preferredStatusBarStyle
método naUINavigationController
categoria não será chamado, o swizzling parece ser a única opção sem a necessidade de usar uma subclasse.Exemplo:
Cabeçalho da categoria:
Implementação:
Uso no AppDelegate.h:
fonte
Aqui está o meu método para resolver isso.
Defina um protocolo chamado AGViewControllerAppearance .
AGViewControllerAppearance.h
Defina uma categoria no UIViewController chamada Upgrade .
UIViewController + Upgrade.h
UIViewController + Upgrade.m
Agora, é hora de dizer que você está vendo o controlador implementando o protocolo AGViewControllerAppearance .
Exemplo:
Obviamente, você pode implementar o restante dos métodos ( showsStatusBar , animatesStatusBarVisibility , prefferedStatusBarAnimation ) a partir do protocolo e o UIViewController + Upgrade fará a personalização adequada com base nos valores fornecidos por eles.
fonte
Se alguém encontrar esse problema com o UISearchController. Apenas crie uma nova subclasse de UISearchController e adicione o código abaixo nessa classe:
fonte
Observe que ao usar a
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
soluçãonão deixe de ir ao seu pedido e defina "Exibir aparência da barra de status com base no controlador" como YES. Se não, não vai funcionar.
fonte
Desde o Xcode 11.4, a substituição da
preferredStatusBarStyle
propriedade em uma extensão UINavigationController não funciona mais, pois não será chamada.Definir a
barStyle
denavigationBar
que.black
obras de fato, mas isso vai adicionar efeitos colaterais indesejados se você adicionar subviews à NavigationBar que pode ter aparências diferentes para o modo claro e escuro. Como a configuraçãobarStyle
para preto, auserInterfaceStyle
visualização incorporada na barra de navegação sempre terá,userInterfaceStyle.dark
independentemente douserInterfaceStyle
aplicativo.A solução adequada que eu encontro é adicionar uma subclasse
UINavigationController
e substituirpreferredStatusBarStyle
lá. Se você usar esse UINavigationController personalizado para todas as suas visualizações, estará no lado de salvar.fonte
O NavigationController ou o TabBarController são os que precisam fornecer o estilo. Aqui está como eu resolvi: https://stackoverflow.com/a/39072526/242769
fonte