web-dev-qa-db-fra.com

Comment empêcher le mode sombre d'iOS 13 de changer la couleur du texte dans la barre d'état de mon application?

Ma barre de navigation a un whitebackgroundColor et ma barre d'état utilise le darktextColor. Lorsqu'un utilisateur modifie le thème iOS en mode sombre, la barre d'état se transforme en white texte sur un arrière-plan white. En conséquence, je ne vois rien. Comment puis-je désactiver cette modification pour mon application?

10
EvGeniy Ilyin

solution (s) iOS 13

UINavigationController est une sous-classe de UIViewController (qui savait ????)!

Par conséquent, lorsque vous présentez des contrôleurs de vue intégrés aux contrôleurs de navigation, vous ne présentez pas vraiment les contrôleurs de vue intégrés; vous présentez les contrôleurs de navigation! UINavigationController, en tant que sous-classe de UIViewController, hérite de preferredStatusBarStyle et childForStatusBarStyle, que vous pouvez définir comme vous le souhaitez.

L'une des méthodes suivantes devrait fonctionner:

  1. Désactiver complètement le mode sombre
    • Dans votre info.plist, ajoutez la propriété suivante:
      • Clé - UIUserInterfaceStyle (alias. "Style d'interface utilisateur")
      • Valeur - Léger
  2. Remplacez preferredStatusBarStyle dans UINavigationController

    • preferredStatusBarStyle ( doc ) - Le style de barre d'état préféré pour le contrôleur de vue
    • Sous-classe ou extension UINavigationController

      class MyNavigationController: UINavigationController {
          override var preferredStatusBarStyle: UIStatusBarStyle {
              .lightContent
          }
      }
      

      OR

      extension UINavigationController {
          open override var preferredStatusBarStyle: UIStatusBarStyle {
              .lightContent
          }
      }
      
  3. Remplacez childForStatusBarStyle dans UINavigationController

    • childForStatusBarStyle ( doc ) - Appelé lorsque le système a besoin du contrôleur de vue à utiliser pour déterminer le style de la barre d'état
    • Selon la documentation d'Apple,

      "Si votre contrôleur de vue de conteneur dérive son style de barre d'état de l'un de ses contrôleurs de vue enfant, [remplacez cette propriété] et renvoyez ce contrôleur de vue enfant. Si vous retournez nil ou ne remplacez pas cette méthode, le style de barre d'état pour self est utilisé . Si la valeur de retour de cette méthode change, appelez la méthode setNeedsStatusBarAppearanceUpdate (). "

    • En d'autres termes, si vous n'implémentez pas la solution 3 ici, le système reviendra à la solution 2 ci-dessus.
    • Sous-classe ou extension UINavigationController

      class MyNavigationController: UINavigationController {
          override var childForStatusBarStyle: UIViewController? {
              topViewController
          }
      }
      

      OR

      extension UINavigationController {    
          open override var childForStatusBarStyle: UIViewController? {
              topViewController
          }
      }
      
    • Vous pouvez retourner n'importe quel contrôleur de vue que vous souhaitez ci-dessus. Je recommande l'une des options suivantes:

      • topViewController (of UINavigationController) ( doc ) - Le contrôleur de vue en haut de la pile de navigation
      • visibleViewController (of UINavigationController) ( doc ) - Le contrôleur de vue associé à la vue actuellement visible dans l'interface de navigation (indice: cela peut inclure "un contrôleur de vue qui a été présenté de façon modale au-dessus du contrôleur de navigation lui-même ")

Remarque: Si vous décidez de sous-classer UINavigationController, n'oubliez pas d'appliquer cette classe à vos contrôleurs de navigation via l'inspecteur d'identité dans IB.

P.S. Mon code utilise la syntaxe Swift 5.1 ????

23
Andrew Kirna

Si vous définissez la clé UIViewControllerBasedStatusBarAppearance dans le info.plist à YES, vous pouvez remplacer le style de la barre d'état dans le contrôleur de vue actuellement présenté:

override var preferredStatusBarStyle: UIStatusBarStyle {
    if #available(iOS 13, *) {
        return .darkContent
    } else {
        return .default
    }
}

et appelez la méthode setNeedsStatusBarAppearanceUpdate ()

8
Frank Schlegel

Vous pouvez écrire l'extension dans UIStatusBarStyle:

extension UIStatusBarStyle {
    static var black: UIStatusBarStyle {
        if #available(iOS 13.0, *) {
            return .darkContent
        }
        return .default
    }
}

Et puis vous pouvez facilement utiliser dans vos ViewControllers:

override var preferredStatusBarStyle: UIStatusBarStyle {
    .black
}
4
buxik

Vous pouvez essayer de rendre votre barre de navigation toujours light

if #available(iOS 13.0, *) {
    navigationController?.navigationBar.overrideUserInterfaceStyle = .light
 }

J'ai fait quelque chose comme ça.

J'ai une fonction de basculement qui bascule le style de la barre d'état en fonction du View Controller affiché

func toggleLight() {
        self.navigationBar.barTintColor = AppColors.White

        isDarkStyle = false
        setNeedsStatusBarAppearanceUpdate()

    }

et voici la partie la plus importante

override var preferredStatusBarStyle: UIStatusBarStyle {

        if #available(iOS 13.0, *) {
            return isDarkStyle ? .lightContent : .darkContent
        }
        return isDarkStyle ? .lightContent : .default
    }

Où isDarkStyle représente la couleur d'arrière-plan de la barre de navigation sombre ou claire. S'il est sombre, le texte (contenu) doit être clair, s'il est clair, le texte (contenu) doit être par défaut ou iOS 13 sombre.

Pour résumer: .lightContent, .darkContent s'affiche indépendamment du mode sombre comme il est censé le faire. Tandis que .default est susceptible de changer de mode sombre!

0
Michał Ziobro

Il existe deux façons de résoudre ce problème. Définissez la fonction childViewControllerForStatusBarStyle dans la classe descendante UINavigationController:

@interface MyNavigationController : UINavigationController
...
@end

@implementation MyNavigationController
...
- (UIViewController *)childViewControllerForStatusBarStyle
{
    return self.topViewController;
}
...
@end

Après cela, vous devez ajouter la fonction PreferredStatusBarStyle pour chaque contrôleur.

La deuxième option consiste à définir la fonction PreferredStatusBarStyle pour tous les contrôleurs. Mais cette fonction ne doit pas se trouver dans le contrôleur racine, mais dans la classe descendante de UINavigationController.

@interface MyNavigationController : UINavigationController
...
@end

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

Cependant, même dans ce cas, il est nécessaire de définir la fonction favoriteStatusBarStyle pour tous les contrôleurs qui masquent la barre de navigation (le cas échéant).

0
Alexey Brilev

Cette extension vous aide à modifier la couleur du texte de la barre d'état et prend également en charge iOS 13 https://stackoverflow.com/a/59767435/10512612

0
Mickael Belhassen

Si vous utilisez un UINavigationController, remplacez le preferredStatusBarStyle dans une extension (ou votre propre sous-classe) comme ceci (remplacez simplement preferredStatusBarStyle dans votre les contrôleurs de vue ne fonctionneront pas):

extension UINavigationController {
  override open var preferredStatusBarStyle: UIStatusBarStyle {
    guard #available(iOS 13, *) else {
      return .default
    }
    return .darkContent
  }
}

Et comme l'a dit Frank, UIViewControllerBasedStatusBarAppearance doit être défini sur YES dans votre info.plist

0
Ricky Padilla