web-dev-qa-db-fra.com

Comment changer UIStatusBarStyle dans iOS 7 dans des vues modales avec barre de navigation?

Le iOS 7 Transition Guide donne un bon indice pour changer dynamiquement la UIStatusBarStyle dans une UIViewController en utilisant

- (UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleDefault;
}

avec [self setNeedsStatusBarAppearanceUpdate];

Cela fonctionne très bien dans une application à vue unique. Cependant, j'essaie maintenant de changer la UIStatusBarStyle dans une vue modale en UIStatusBarStyleLightContent. Il existe une MainViewController qui suit la ModalViewController, elle-même intégrée à une NavigationController. La ModalViewController a défini son délégué sur la MainViewController.

J'ai essayé d'appeler [self setNeedsStatusBarAppearanceUpdate]; dans la ModalViewController avec la méthode suivante dans cette classe sans effet:

// In ModalViewController.m
- (UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleLightContent;
}

J'ai aussi essayé d'appeler [self setNeedsStatusBarAppearanceUpdate]; dans MainViewController sur la méthode prepareForSegue: sender: avec des conditions dans - (UIStatusBarStyle)preferredStatusBarStyle {} pour renvoyer UIStatusBarStyleLightContent lorsque la vue modale est présentée - mais cela n'a aucun effet.

Comment modifier le UIStatusBarStyle dans la vue modale?

EDIT: Post updated: Je dois mentionner que la ModalViewController est incorporée dans une NavigationController avec une NavigationBar. Si NavigationBar est défini sur hidden, l'appel ci-dessus de [self setNeedsStatusBarAppearanceUpdate]; dans ModalViewController fonctionne correctement. Mais pas quand le bar est visible.

11
FrankZp

Vous avez besoin d'un ViewController affiché en plein écran pour renvoyer les informations de barre d'état appropriées. Dans votre cas: Le NavigationController qui contient ModalViewController doit implémenter preferredStatusBarStyle et retourner UIStatusBarStyleLightContent.

Un appel à setNeedsStatusBarAppearanceUpdate n'est nécessaire que si les valeurs renvoyées par un contrôleur de vue changent réellement. Lorsque le contrôleur de vue est présenté pour la première fois, ils sont quand même interrogés.

28
jaetzold

On notera que modalVCNON-PLEIN ÉCRAN PEUTutiliser modalPresentationCapturesStatusBarAppearance pour contrôler le style statusBar.

Quiconque souhaite en savoir plus sur le contrôle de la barre d'état ne doit pas ignorer le UIViewController Gestion de la barre d'état .

Mise à jour au 06/11/2015:

Et assurez-vous que vous avez défini la variable UIViewControllerBasedStatusBarAppearance décrite dans Clés iOS

Mise à jour au 2018.04.09:

J'ai remarqué que viewController dans un navController peut ne pas recevoir l'appel prefersStatusBarHidden avec iOS 10.0 - 10.2. Personnalisez votre navigationController pour vous assurer que

@implementation YourCustomNavController
//for iOS 10.0 - iOS 10.2
- (BOOL)prefersStatusBarHidden {
    UIViewController *childVC = [self childViewControllerForStatusBarHidden];
    if (childVC) {
        return [childVC prefersStatusBarHidden];
    }
    return [super prefersStatusBarHidden];
}
@end

Et tous ceux qui veulent aller plus loin peuvent creuser dans UIKit +[UIViewController _currentStatusBarStyleViewController] en utilisant Hopper ou IDA Pro. Cela peut vous aider à résoudre ce type de bugs.

24
Puttin

Pour que cela fonctionne, seul le contrôleur de vue plein écran peut dicter le style de la barre d'état.

Si vous utilisez un contrôleur de navigation et souhaitez contrôler la barre d'état contrôleur par vue, vous souhaiterez sous-classer UINavigationController et implémenter preferredStatusBarStyle de sorte qu'il renvoie la préférence de topViewController.

Assurez-vous de changer la référence de classe dans votre scène de storyboard d'UINavigationController à votre sous-classe (par exemple, MyNavigationController dans l'exemple ci-dessous).

(Ce qui suit fonctionne pour moi. Si votre application est basée sur TabBar, vous voudrez faire quelque chose de similaire en sous-classant UITabBarController mais je ne l'ai pas encore essayé).

@interface MyNavigationController : UINavigationController

@end

@implementation MyNavigationController

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return self.topViewController.preferredStatusBarStyle;
}

@end
11
Juddster

Pour modifier la barre d'état de UINavigationController incorporant votre ViewController sans sous-classer UINavigationController, utilisez ceci:

navigationController?.navigationBar.barStyle = .Black // to make the status bar text white

.Black rend le texte blanc (barre d'état et titre de la vue), alors que .Default a un titre et une barre d'état noirs.

6
Alex Wally

J'avais un contrôleur de menu/révéler latéral (SWRevealController) qui s'avère toujours être le contrôleur racine pour les requêtes de barre d'état. En remplaçant childViewControllerForStatusBarStyle, laissez-moi ré-acheminer la requête au contrôleur le plus à l'avant.

/**
 This view is always considered the topmost for status bar color queries.
 Pass the query along to what we're showing in front.
 */
- (UIViewController *)childViewControllerForStatusBarStyle
{
    UIViewController *front = self.frontViewController;
    if ([front isKindOfClass:[UINavigationController class]])
        return ((UINavigationController*)front).topViewController;
    else
        return front;
}
2
Graham Perks

Cela fonctionne pour moi:

  1. Définissez View controller-based status bar appearance sur NO
  2. Définissez le style de la barre d'état sur UIStatusBarStyleLightContent (copiez simplement cette valeur)
  3. Dans appDelegate, utilisez [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

J'espère que cela vous aidera (réf: la barre d'état de ios7 redevient noire sur les vues modales? )

1
samthui7

Il semble que l'application se désactive du statusBarStyle du plus haut viewController. Donc, si vous ajoutez un autre viewController au-dessus de votre actuel, il reçoit maintenant ses repères du nouveau viewController.

1
William Jockusch

Il suffit de regarder si la commande rootViewController de votre application doit remplacer la méthode - (UIStatusBarStyle), méthode preferredStatusBarStyle

0
devClown

Tout ce qui précède fonctionne. Cependant, quelquefois, je trouve vraiment difficile de changer chaque instance du Storyboard, etc.

Commencez par créer la sous-classe:

@interface HHNavLightColorBarController : UINavigationController

@end

@implementation HHNavLightColorBarController

- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}
@end

Ensuite, en utilisant la magie d'Objective-C et un peu de <objc/runtime.h>

Lorsque vous avez une référence du contrôleur de vue et que vous la présentez:

UINavigationController *navVC = ...; // Init in your usual way
object_setClass(navVC, [HHNavLightColorBarController class]);
[self presentViewController:nav animated:YES completion:^{
    NSLog(@"Launch Modal View Controller");
}];

Parfois, cela semble un peu moins intrusif. Vous pourriez probablement même créer une catégorie qui vérifie si votre kindOfClass est un contrôleur de navigation et le fait automatiquement pour vous. Quoi qu'il en soit, jaetzold a déjà répondu à cette question, je viens de le trouver très pratique.

0
bainfu