preferredStatusBarStyle n'est pas appelé

j'ai suivi ce thread pour remplacer -preferredStatusBarStyle , mais il n'est pas appelé. Sont-il des options que je peux changer pour l'activer? (J'utilise XIBs dans mon projet.)

218
demandé sur Community 2013-09-26 11:42:14

21 réponses

cause Possible

j'ai eu le même problème, et j'ai compris que c'était parce que je ne réglais pas le contrôleur de vue racine dans ma fenêtre d'application.

le UIViewController dans lequel j'avais mis en œuvre le preferredStatusBarStyle était utilisé dans un UITabBarController , qui contrôlait l'apparence des vues sur l'écran.

quand j'ai défini le contrôleur de vue racine pour pointer vers ce UITabBarController , la barre d'état change a commencé à fonctionner correctement, comme prévu (et la méthode preferredStatusBarStyle a été appelé).

(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ... // other view controller loading/setup code

    self.window.rootViewController = rootTabBarController;
    [self.window makeKeyAndVisible];
    return YES;
}

méthode Alternative (Déconseillé dans iOS 9)

alternativement, vous pouvez appeler l'une des méthodes suivantes, selon le cas, dans chacun de vos contrôleurs de vue, en fonction de sa couleur de fond, au lieu d'avoir à utiliser setNeedsStatusBarAppearanceUpdate :

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

ou

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

notez que vous il faut aussi définir UIViewControllerBasedStatusBarAppearance à NO dans le fichier plist si vous utilisez cette méthode.

105
répondu AbdullahC 2016-10-07 21:51:39

pour toute personne utilisant un contrôleur Uinavigation:

le UINavigationController ne transmet pas sur preferredStatusBarStyle les appels à ses contrôleurs de vision d'enfant. Au lieu de cela, il gère son propre état - comme il se doit, il dessine en haut de l'écran où la barre de statut vit et devrait donc être responsable de lui. Par conséquent, l'implémentation de preferredStatusBarStyle dans votre VCs à l'intérieur d'un contrôleur nav ne fera rien - ils ne seront jamais appelés.

le truc est ce que le UINavigationController utilise pour décider quoi retourner pour UIStatusBarStyleDefault ou UIStatusBarStyleLightContent . Il se base sur son UINavigationBar.barStyle . Le résultat par défaut ( UIBarStyleDefault ) est la barre d'état de dark forground UIStatusBarStyleDefault . Et UIBarStyleBlack donnera une barre de statut UIStatusBarStyleLightContent .

TL; DR:

si vous voulez UIStatusBarStyleLightContent sur un UINavigationController utiliser:

self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
931
répondu Tyson 2018-01-25 23:31:28

donc j'ai en fait ajouté une catégorie à UINavigationController mais j'ai utilisé les méthodes:

-(UIViewController *)childViewControllerForStatusBarStyle;
-(UIViewController *)childViewControllerForStatusBarHidden;

et que ceux-ci renvoient le UIViewController visible courant. Cela permet au contrôleur de vue visible actuel de définir son propre style/visibilité préféré.

voici un extrait de code complet pour lui:

Dans Swift:

extension UINavigationController {

    public override func childViewControllerForStatusBarHidden() -> UIViewController? {
        return self.topViewController
    }

    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return self.topViewController
    }
}

Dans Objectif-C:

@interface UINavigationController (StatusBarStyle)

@end

@implementation UINavigationController (StatusBarStyle)

-(UIViewController *)childViewControllerForStatusBarStyle {
    return self.topViewController;
}

-(UIViewController *)childViewControllerForStatusBarHidden {
    return self.topViewController;
}

@end

et pour faire bonne mesure, voici comment il est mis en œuvre alors dans un UIViewController:

Swift

override public func preferredStatusBarStyle() -> UIStatusBarStyle {
    return .LightContent
}

override func prefersStatusBarHidden() -> Bool {
    return false
}

Dans L'Objectif - C

-(UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent; // your own style
}

- (BOOL)prefersStatusBarHidden {
    return NO; // your own visibility code
}

Enfin, assurez-vous que votre application ne pas ont l '"apparence de la barre d'état basée sur le contrôleur de vue" définie à NO. Supprimer la ligne ou OUI (que j' croyez est la valeur par défaut maintenant pour iOS 7?)

83
répondu serenn 2016-03-03 09:08:40

pour quiconque est encore aux prises avec ce problème, cette simple extension dans swift devrait résoudre le problème pour vous.

extension UINavigationController {
    override open var childViewControllerForStatusBarStyle: UIViewController? {
        return self.topViewController
    }
}
46
répondu Alex Brown 2017-02-17 15:21:48

la réponse de Tyson est correcte pour changer la couleur de la barre d'état en blanc dans UINavigationController .

si quelqu'un veut accomplir le même résultat en écrivant le code dans AppDelegate puis utiliser le code ci-dessous et l'écrire dans AppDelegate's " méthode 151940920".

et n'oubliez pas de définir le UIViewControllerBasedStatusBarAppearance à YES dans le .plist, sinon le changement ne reflètera pas.

Code

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     // status bar appearance code
     [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];

     return YES;
}
14
répondu Yogesh Suthar 2015-05-23 11:33:47

un ajout à la réponse D'Hippo: si vous utilisez un UINavigationController, alors il est probablement préférable d'ajouter une catégorie:

//  UINavigationController+StatusBarStyle.h:

@interface UINavigationController (StatusBarStyle)

@end



//  UINavigationController+StatusBarStyle.m:

@implementation UINavigationController (StatusBarStyle)

- (UIStatusBarStyle)preferredStatusBarStyle
{
    //also you may add any fancy condition-based code here
    return UIStatusBarStyleLightContent;
}

@end

cette solution est probablement meilleure que le passage à un comportement bientôt déprécié.

9
répondu Artem Abramov 2013-10-15 05:02:23

@serenn réponse ci-dessus est toujours un grand pour le cas de UINavigationControllers. Toutefois, pour swift 3, les fonctions de childViewController ont été changées en vars . Ainsi ,le code d'extension UINavigationController devrait être:

override open var childViewControllerForStatusBarStyle: UIViewController? {
  return topViewController
}

override open var childViewControllerForStatusBarHidden: UIViewController? {
  return topViewController
}

et ensuite dans le contrôleur de vue qui devrait dicter le style de la barre d'état:

override var preferredStatusBarStyle: UIStatusBarStyle {
   return .lightContent
}
6
répondu John Stricker 2017-05-23 11:54:59

si votre viewController est sous UINavigationController.

sous-classe UINavigationController et ajouter

override var preferredStatusBarStyle: UIStatusBarStyle {
    return topViewController?.preferredStatusBarStyle ?? .default
}

ViewController preferredStatusBarStyle sera appelée.

5
répondu PowHu 2016-10-29 11:45:21

mon application utilisait les trois: UINavigationController , UISplitViewController , UITabBarController , ainsi, toutes ces personnes semblent prendre le contrôle de la barre de statut et feront en sorte que preferedStatusBarStyle ne soit pas appelé pour leurs enfants. Pour remplacer ce comportement, vous pouvez créer une extension comme le reste des réponses ont mentionné. Voici une extension pour les trois, dans Swift 4. J'aimerais Qu'Apple soit plus clair sur ce genre de choses.

extension UINavigationController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return self.topViewController
    }

    open override var childViewControllerForStatusBarHidden: UIViewController? {
        return self.topViewController
    }
}

extension UITabBarController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return self.childViewControllers.first
    }

    open override var childViewControllerForStatusBarHidden: UIViewController? {
        return self.childViewControllers.first
    }
}

extension UISplitViewController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return self.childViewControllers.first
    }

    open override var childViewControllerForStatusBarHidden: UIViewController? {
        return self.childViewControllers.first
    }
}
5
répondu Luis 2018-02-01 04:15:53

UIStatusBarStyle in iOS 7

la barre d'état dans iOS 7 est transparente, la vue derrière elle montre à travers.

le style de la barre de statut se réfère aux apparences de son contenu. Dans iOS 7, le contenu de la barre d'état est soit sombre ( UIStatusBarStyleDefault ) ou clair ( UIStatusBarStyleLightContent ). Les deux UIStatusBarStyleBlackTranslucent et UIStatusBarStyleBlackOpaque sont dépréciés dans iOS 7.0. Utilisez UIStatusBarStyleLightContent à la place.

comment changer UIStatusBarStyle

si au-dessous de la barre d'état se trouve une barre de navigation, le style de la barre d'état sera ajusté pour correspondre au style de la barre de navigation ( UINavigationBar.barStyle ):

plus précisément, si le style de barre de navigation est UIBarStyleDefault, le style de barre d'état sera UIStatusBarStyleDefault ; si le style de barre de navigation est UIBarStyleBlack , le style de barre d'état sera UIStatusBarStyleLightContent .

s'il n'y a pas de barre de navigation sous la barre d'état, la barre d'état le style peut être contrôlé et modifié par un contrôleur de vue individuel pendant que l'application tourne.

- [UIViewController preferredStatusBarStyle] est une nouvelle méthode ajoutée dans iOS 7. Il peut être annulé pour retourner le style de barre de statut préféré:

- (UIStatusBarStyle)preferredStatusBarStyle
  {
      return UIStatusBarStyleLightContent;
  }

si le style de la barre d'État doit être contrôlé par un contrôleur de vue enfant plutôt que par soi-même, outrepasser -[UIViewController childViewControllerForStatusBarStyle] pour retourner ce contrôleur de vue enfant.

Si vous préférez vous retirer de ce comportement et définissez le style de la barre d'état en utilisant la méthode -[UIApplication statusBarStyle] , ajoutez la touche UIViewControllerBasedStatusBarAppearance au fichier Info.plist d'une application et donnez-lui la valeur NO.

4
répondu oscarr 2015-10-27 15:39:22

si quelqu'un utilise un contrôleur de Navigation et veut que tous ses contrôleurs de navigation aient le style noir, vous pouvez écrire une extension à UINavigationController comme ceci dans Swift 3 et elle s'appliquera à tous les contrôleurs de navigation (au lieu de l'assigner à un contrôleur à la fois).

extension UINavigationController {

    override open func viewDidLoad() {
        super.viewDidLoad()

        self.navigationBar.barStyle = UIBarStyle.black
    }

}
4
répondu Benjamin Lowry 2017-01-11 13:54:01

sur un UINavigationController, preferredStatusBarStyle n'est pas appelé parce que son topViewController est préféré à self . Ainsi, pour obtenir preferredStatusBarStyle appelé sur un UINavigationController, vous devez changer son childViewControllerForStatusBarStyle .

De le faire pour un UINavigationController (ma recommandation):

class MyRootNavigationController: UINavigationController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    override var childViewControllerForStatusBarStyle: UIViewController? {
        return nil
    }
}

De le faire pour tous les UINavigationController (attention: il affecte UIDocumentPickerViewController, UIImagePickerController, etc.):

extension UINavigationController {
    public override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    public override var childViewControllerForStatusBarStyle: UIViewController? {
        return nil
    }
}
3
répondu Cœur 2018-07-12 17:20:27

Swift 3 Solution iOS 10:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
 }
2
répondu Statik 2016-10-05 11:15:00

voici ma méthode pour résoudre ceci.

définit un protocole appelé AGViewControllerAppearance .

AGViewControllerAppearance.h

#import <Foundation/Foundation.h>

@protocol AGViewControllerAppearance <NSObject>

@optional

- (BOOL)showsStatusBar;
- (BOOL)animatesStatusBarVisibility;
- (UIStatusBarStyle)preferredStatusBarStyle;
- (UIStatusBarAnimation)prefferedStatusBarAnimation;

@end

Définir une catégorie UIViewController appelé Mise à niveau .

UIViewController+Mise À Niveau.h

#import <UIKit/UIKit.h>

@interface UIViewController (Upgrade)

//
//  Replacements
//

- (void)upgradedViewWillAppear:(BOOL)animated;

@end

UIViewController+Mise À Niveau.m

#import "UIViewController+Upgrade.h"

#import <objc/runtime.h>

#import "AGViewControllerAppearance.h" // This is the appearance protocol

@implementation UIViewController (Upgrade)

+ (void)load
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wselector"
    Method viewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:));
#pragma clang diagnostic pop
    Method upgradedViewWillAppear = class_getInstanceMethod(self, @selector(upgradedViewWillAppear:));
    method_exchangeImplementations(viewWillAppear, upgradedViewWillAppear);
}

#pragma mark - Implementation

- (void)upgradedViewWillAppear:(BOOL)animated
{
    //
    //  Call the original message (it may be a little confusing that we're
    //  calling the 'same' method, but we're actually calling the original one :) )
    //

    [self upgradedViewWillAppear:animated];

    //
    //  Implementation
    //

    if ([self conformsToProtocol:@protocol(AGViewControllerAppearance)])
    {
        UIViewController <AGViewControllerAppearance> *viewControllerConformingToAppearance =
        (UIViewController <AGViewControllerAppearance> *)self;

        //
        //  Status bar
        //

        if ([viewControllerConformingToAppearance respondsToSelector:@selector(preferredStatusBarStyle)])
        {
            BOOL shouldAnimate = YES;

            if ([viewControllerConformingToAppearance respondsToSelector:@selector(animatesStatusBarVisibility)])
            {
                shouldAnimate = [viewControllerConformingToAppearance animatesStatusBarVisibility];
            }

            [[UIApplication sharedApplication] setStatusBarStyle:[viewControllerConformingToAppearance preferredStatusBarStyle]
                                                        animated:shouldAnimate];
        }

        if ([viewControllerConformingToAppearance respondsToSelector:@selector(showsStatusBar)])
        {
            UIStatusBarAnimation animation = UIStatusBarAnimationSlide;

            if ([viewControllerConformingToAppearance respondsToSelector:@selector(prefferedStatusBarAnimation)])
            {
                animation = [viewControllerConformingToAppearance prefferedStatusBarAnimation];
            }

            [[UIApplication sharedApplication] setStatusBarHidden:(! [viewControllerConformingToAppearance showsStatusBar])
                                                    withAnimation:animation];
        }
    }
}

@end

maintenant, il est temps de dire que votre contrôleur de vue implémente le protocole AGViewControllerAppearance .

exemple:

@interface XYSampleViewController () <AGViewControllerAppearance>

... the rest of the interface

@end

bien sûr, vous pouvez mettre en œuvre le reste des méthodes ( showsStatusBar , animatesStatusBarVisibility , preferedstatusbaranimation ) du protocole et UIViewController+Upgrade fera le bon la personnalisation basée sur les valeurs fournies par eux.

0
répondu arturgrigor 2014-01-11 23:25:55

si quelqu'un rencontre ce problème avec UISearchController. Il suffit de créer une nouvelle sous-classe de UISearchController, puis d'ajouter le code ci-dessous dans cette classe:

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return .LightContent
}
0
répondu Tai Le 2015-07-19 13:50:40

rapide pour tout type de UIViewController:

dans votre AppDelegate set:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    window!.rootViewController = myRootController
    return true
}

myRootController peut être tout type de UIViewController , p.ex. UITabBarController ou UINavigationController .

alors, outrepasser ce contrôleur racine comme ceci:

class RootController: UIViewController {
    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return .LightContent
    }
}

cela va changer l'apparence de la barre d'état dans l'ensemble de votre application, parce que le contrôleur root est uniquement responsable de la barre d'état de l'apparence.

n'oubliez pas de définir la propriété View controller-based status bar appearance sur " OUI " dans votre Info.plist pour faire ce travail (qui est la valeur par défaut).

0
répondu Damnum 2016-07-22 09:10:51

noter que lors de l'utilisation de la self.navigationController.navigationBar.barStyle = UIBarStyleBlack; solution

assurez-vous d'aller sur votre liste et de régler" afficher l'apparence de la barre d'état basée sur le contrôleur " à Oui. Si ses PAS, cela ne fonctionnera pas.

0
répondu Richard Garfield 2016-10-21 17:20:19

en plus de la réponse de serenn, si vous présentez un contrôleur de vue avec un modalPresentationStyle (par exemple .overCurrentContext ), vous devez également l'appeler sur le contrôleur de vue Nouvellement présenté:

presentedViewController.modalPresentationCapturesStatusBarAppearance = true

n'oubliez pas d'outrepasser également le preferredStatusBarStyle dans le contrôleur de vue présenté.

0
répondu frin 2018-09-18 14:32:22

la plupart des réponses ne comprennent pas une bonne mise en œuvre de childViewControllerForStatusBarStyle méthode pour UINavigationController . Selon mon expérience, vous devriez traiter de tels cas comme lorsque le contrôleur de vue transparent est présenté sur le contrôleur de navigation. Dans ces cas, vous devez passer le contrôle à votre contrôleur modal ( visibleViewController ), mais pas quand il disparaît.

override var childViewControllerForStatusBarStyle: UIViewController? {
  var childViewController = visibleViewController
  if let controller = childViewController, controller.isBeingDismissed {
    childViewController = topViewController
  }
  return childViewController?.childViewControllerForStatusBarStyle ?? childViewController
}
0
répondu Timur Bernikowich 2018-10-03 13:38:23

pour changer la couleur du texte de la barre d'état dans iOS 10 & iOS 11:

Voici les cas pour la barre D'état basée sur ViewController apparence:

1) ViewController sans NavigationController:

-(UIStatusBarStyle)preferredStatusBarStyle {
      return UIStatusBarStyleLightContent;// Change according to your need
}

2) ViewController avec un NavigationController:

self.navigationController.navigationBar.barStyle = UIStatusBarStyleLightContent; // Change according to your need

ci-dessous est pour changer la couleur du texte de la barre d'État pour l'ensemble application:

a) Add "View controller-based status bar appearance" in info.plist and set it to NO
b) Write following code in didFinishLaunchingWithOptions in AppDelegate as:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

       [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; // Change according to your need
       return YES;
   } 
-1
répondu Shahul Hasan 2018-09-25 10:41:33

le NavigationController ou TabBarController sont ceux qui doivent fournir le style. Voici comment j'ai résolu: https://stackoverflow.com/a/39072526/242769

-2
répondu aryaxt 2017-05-23 12:34:45