Dans mon application iPhone construite avec Xcode 5 pour iOS 7, j'ai défini UIViewControllerBasedStatusBarAppearance=YES
dans info.plist
, et dans mon ViewController
j'ai ce code:
-(UIStatusBarStyle) preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
Mais la barre d'état est toujours noire sur le fond noir.
Je sais qu'il est possible de changer cette application en définissant UIViewControllerBasedStatusBarAppearance=NO
dans info.plist
, mais je dois en fait modifier cela viewController
de viewController
à l'exécution.
OK, voici le truc. Vous devez ajouter la clé "Afficher la barre d'état basée sur le contrôleur" et définir la valeur sur Non.
Ceci est contraire à la signification apparente de cette clé, mais même si vous définissez la valeur sur No
, vous pouvez toujours modifier l'apparence de la barre d'état, qu'elle soit affichée ou non dans un contrôleur de vue. . Donc, il agit comme "Oui" mais réglez-le sur "Non"!
Maintenant, je peux obtenir la barre d'état blanche ou sombre.
J'ai découvert que si votre ViewController est à l'intérieur d'un navigationController, alors le navigationBar.barStyle
détermine le statusBarStyle.
Régler le paramètre barStyle
de votre barre de navigation sur UIBarStyleBlackTranslucent
donnera un texte de barre d'état blanche (c'est-à-dire UIStatusBarStyleLightContent
) et UIBarStyleDefault
donnera un texte de barre d'état noire (c'est-à-dire UIStatusBarStyleDefault
).
Note Cela s’applique même si vous changez totalement la couleur de la barre de navigation via son barTintColor
.
Pour que preferredStatusBarStyle()
fonctionne dans UINavigationController
et UITabBarController
, j'ajoute le code suivant, qui obtiendra le style de barre d'état préféré du contrôleur de vue actuellement visible.
extension UITabBarController {
public override func childViewControllerForStatusBarStyle() -> UIViewController? {
return selectedViewController
}
}
extension UINavigationController {
public override func childViewControllerForStatusBarStyle() -> UIViewController? {
return visibleViewController
}
}
Pour Swift ce ne sont pas des méthodes mais des propriétés:
extension UITabBarController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return selectedViewController
}
}
extension UINavigationController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return visibleViewController
}
}
Les propriétés Swift 4.2 ont été renommées:
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return selectedViewController
}
}
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return visibleViewController
}
}
tilisation
class ViewController: UIViewController {
// This will be called every time the ViewController appears
// Works great for pushing & popping
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
J'arrive peut-être un peu tard, mais si quelqu'un d'autre cherchait une solution efficace et vérifiée au niveau de l'application.
@mxcl décrit correctement pourquoi cela se produit. Afin de le corriger, nous créons simplement une extension (ou une catégorie dans obj-c) qui remplace la méthode preferredSatusBarStyle () de UINavigationController. Voici un exemple dans Swift:
extension UINavigationController {
public override func preferredStatusBarStyle() -> UIStatusBarStyle {
if let rootViewController = self.viewControllers.first {
return rootViewController.preferredStatusBarStyle()
}
return super.preferredStatusBarStyle()
}
}
Ce code extrait simplement le premier contrôleur de vue (le contrôleur de vue racine) et le décompresse (dans obj-c, vérifiez simplement qu'il n'est pas nul). Si le déroulement est réussi (et non nul), nous récupérons le rootViewControllers preferredStatusBarStyle. Sinon, nous renvoyons simplement la valeur par défaut.
J'espère que cela aidera tous ceux qui pourraient en avoir besoin.
Pour fournir plus de détails dans la réponse acceptée, insérez la ligne suivante dans la méthode didFinishLaunchingWithOptions:
Du délégué de votre application:
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
Ensuite, dans votre Info.plist, ajoutez View controller-based status bar appearance
Et définissez-le sur NO
.
Je crois que c'est comme cela que cela devrait être fait, PAS à partir du contrôleur de navigation, si vous voulez la même couleur de barre d'état pour l'ensemble de l'application. Vous avez peut-être des écrans qui ne sont pas nécessairement intégrés à une UINavigationController
, ou une autre sous-classe UINavigationController
, et ailleurs.
[~ # ~] edit [~ # ~] : Vous pouvez également le faire sans saisir de code: https: // stackoverflow. com/a/18732865/85568
Dans viewDidLoad, écrivez simplement ceci
[self setNeedsStatusBarAppearanceUpdate];
faites juste ça et ça marchera
pouvez-vous s'il vous plaît essayer cela
Set UIViewControllerBasedStatusBarAppearance to NO.
Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
Une dernière chose que j'ai vue dans votre question, c'est que vous avez écrit la méthode comme celle-ci.
-(void)UIStatusBarStyle PreferredStatusBarStyle ()
{
return UIStatusBarStyle.LightContent;
}
mais ça devrait être comme ça
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
Voici comment je l'ai résolu. Ce sont généralement les navigateursContrôleur ou TabBarController qui décident de l’aspect de la barre d’état (masqué, couleur, etc.).
Je me suis donc retrouvé à sous-classer le contrôleur de navigation et à redéfinir preferredStatusBarStyle. si le ViewContorller visible actuel implémente StatusBarStyleHandler, je demande que la valeur soit utilisée comme style, sinon je retourne une valeur par défaut.
Pour déclencher une mise à jour de l'apparence de la barre d'état, appelez setNeedsStatusBarAppearanceUpdate
, ce qui déclenche à nouveau preferredStatusBarStyle
et met à jour l'interface utilisateur en fonction des informations renvoyées par la méthode.
public protocol StatusBarStyleHandler {
var preferredStatusBarStyle: UIStatusBarStyle { get }
}
public class CustomNavigationCotnroller: UINavigationController {
public override var preferredStatusBarStyle: UIStatusBarStyle {
if let statusBarHandler = visibleViewController as? StatusBarStyleHandler {
return statusBarHandler.preferredStatusBarStyle
}
return .default
}
}
Puis utilisation
public class SomeController: UIViewController, StatusBarStyleHandler {
private var statusBarToggle = true
// just a sample for toggling the status bar style each time method is called
private func toggleStatusBarColor() {
statusBarToggle = !statusBarToggle
setNeedsStatusBarAppearanceUpdate()
}
public override var preferredStatusBarStyle: UIStatusBarStyle {
return statusBarToggle ? .lightContent : .default
}
}
Même avec toutes les réponses ici je n'ai toujours pas trouvé la solution exacte pour moi, mais a commencé avec la réponse de Daniel. Ce que j'ai fini par être:
override var preferredStatusBarStyle: UIStatusBarStyle {
return visibleViewController?.preferredStatusBarStyle ?? .lightContent
}
dans les contrôleurs de navigation (similaire pour onglet, juste selectedViewController). Et puis il respectera le:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Dans chaque contrôleur de vue, sauf indication contraire de votre part. Je n'ai pas besoin d'appeler setNeedsStatusBarAppearanceUpdate()
n'importe où, il se met simplement à jour lorsque vous arrivez à chaque contrôleur de vue.
1) Un paramètre pour l'ensemble du projet:
Si disponible, supprimez UIViewControllerBasedStatusBarAppearance
la paire clé-valeur de votre info.plist ou définissez NO
sans la supprimer. Si ce n'est pas disponible dans votre info.plist, ne faites rien. La valeur par défaut est NO
pour cette propriété.
Ajoutez le code ci-dessous à votre AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
2) Paramètres différents pour différents contrôleurs de vue:
Ajoutez la paire UIViewControllerBasedStatusBarAppearance
à votre info.plist et réglez-la sur YES
.
Si votre View Controller n'est pas intégré au contrôleur de navigation. Disons MyViewController. ajoutez simplement le code ci-dessous à votre fichier MyViewController.m. Si votre contrôleur de vue est intégré au contrôleur de navigation, créez une nouvelle classe Cocoa Touch et faites-en une sous-classe de UINavigationController. Disons MyNC. Sélectionnez la vue Contrôleur de navigation sur votre Storyboard, dans le volet de droite; Utilitaires -> Inspecteur d'identité -> Classe personnalisée -> Classe, tapez "MyNC". Après avoir lié la vue Storyboard à votre classe "MyNC" Cocoa Touch, ajoutez le code ci-dessous à votre MyNC.m:
- (BOOL)prefersStatusBarHidden {
return NO;
}
-(UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
Swift 4.2
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return selectedViewController
}
}
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return visibleViewController
}
}
Si vous utilisez NavigationController
, vous pouvez sous-classer NavigationController
pour qu'il consulte son contrôleur de vue enfant.
// MyCustomNavigationController
- (NSUInteger)supportedInterfaceOrientations {
UIViewController *viewControllerToAsk = [self findChildVC];
return [viewControllerToAsk supportedInterfaceOrientations];
}
- (BOOL)shouldAutorotate {
UIViewController *viewControllerToAsk = [self findChildVC];
return [viewControllerToAsk shouldAutorotate];
}
- (UIStatusBarStyle)preferredStatusBarStyle {
UIViewController *viewControllerToAsk = [self findChildVC];
return [viewControllerToAsk preferredStatusBarStyle];
}
- (UIViewController *)findChildVC {
return self.viewControllers.firstObject;
}
Exemple rapide
dans AppDelegate.Swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent;
return true
}
dans info.plist définir l'affichage de l'apparence de la barre d'état basée sur le contrôleur: NON
Si dans le cas où vous vouliez masquer la barre de statut pendant splashScreen mais que vous vouliez changer le style en contenu clair (StatusBarInitiallyHidden sur Plist doit être NON pour masquer la barre de statut sur splash), vous pouvez l'ajouter à la méthode didFinishLaunchingWithOptions d'appDelegate pour la remplacer par lightContent.
[[UIApplication sharedApplication]setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
[[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
Vous pouvez définir le style de la barre d'état. Elle ressemblera à la barre d’état telle que IOS 6 et moins.
Collez cette méthode dans votre contrôleur de vue
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleBlackOpaque;
}
et appelez cette méthode de vue ne charge comme ça
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f)
{
[self setNeedsStatusBarAppearanceUpdate];
}
Je veux juste ajouter une note pour un cas spécifique que j'ai rencontré. J'avais une autre UIWindow dans mon application pour afficher un visage de discussion flottant dans mon application tout le temps. Faire cela n'a causé aucune des solutions ci-dessus, et je ne sais pas trop pourquoi! Tout ce que j'ai remarqué, c'est que mon ViewController dans la nouvelle UIWindow en était la raison! Et si je veux changer le style de la barre d'état, je dois le faire dans le contrôleur de vue de la nouvelle UIWindow.
Cette note pourrait aider d'autres personnes ayant une structure similaire! Donc, fondamentalement, vous pouvez appliquer les solutions mentionnées ci-dessus dans le ViewController de la nouvelle UIWindow.
Encore une fois c'est un cas spécifique.
Merci