Xcode 11.4. La couleur du titre de navigation est devenue NOIRE du storyboard

55

J'ai récemment mis à jour mon Xcode vers 11.4. Lorsque je lance l'application sur l'appareil, j'ai remarqué que tous les titres de mes éléments de navigation étaient complètement noirs lorsqu'ils étaient définis à partir du storyboard. entrez la description de l'image ici

Vous ne pouvez pas changer le code non plus, la ligne de code suivante ne fonctionne plus

self.navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]

Je le fais fonctionner uniquement en utilisant des trucs iOS 13 UINavigationBarAppearance

@available(iOS 13.0, *)
    private func setupNavigationBar() {
        let app = UINavigationBarAppearance()
        app.titleTextAttributes = [.foregroundColor: UIColor.white]
        app.backgroundColor = Constants.Color.barColor
        self.navigationController?.navigationBar.compactAppearance = app
        self.navigationController?.navigationBar.standardAppearance = app
        self.navigationController?.navigationBar.scrollEdgeAppearance = app

        self.navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
    }

Quelqu'un peut-il m'expliquer pourquoi ??? C'est un bug crucial, ou une nouvelle fonctionnalité cachée?

Tudor Popa
la source
3
Même problème ici et je ne trouve rien à faire pour corriger cela. Je pense que c'est un bug: /
Jordan Favray
Pomme. Uggh. Vraiment?
Daniel
essayez celui-ci stackoverflow.com/a/61003557/3887987
Amrit Tiwari
il s'agit du générateur d'interfaces Xcode Mise à jour de bogue XCode vers 11.4.1
NinjaDeveloper

Réponses:

36

Cela m'a corrigé, en utilisant plutôt UINavigationBarAppearance, à partir de: Personnalisation de la barre de navigation de votre application

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = UIColor.black
    appearance.titleTextAttributes = [.foregroundColor: UIColor.white] // With a red background, make the title more readable.
    self.navigationBar.standardAppearance = appearance
    self.navigationBar.scrollEdgeAppearance = appearance
    self.navigationBar.compactAppearance = appearance // For iPhone small navigation bar in landscape.
} else {
    self.navigationBar.barTintColor = UIColor.black
    self.navigationBar.tintColor = UIColor.white
    self.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
}

Remarque: J'ai sous- classé UINavigationController , et cela a été appelé à partir du remplacement de viewWillAppear .

... ou pour AppDelegate , à l' échelle de l' application:

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = UIColor.black
    appearance.titleTextAttributes = [
        NSAttributedStringKey.foregroundColor: UIColor.white
    ]

    let buttonAppearance = UIBarButtonItemAppearance()
    buttonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.white]
    appearance.buttonAppearance = buttonAppearance

    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
    UINavigationBar.appearance().compactAppearance = appearance

    UIBarButtonItem.appearance().tintColor = UIColor.white
} else {
    UINavigationBar.appearance().barTintColor = UIColor.black
    UINavigationBar.appearance().titleTextAttributes = [
        NSAttributedStringKey.foregroundColor: UIColor.white
    ]
    UINavigationBar.appearance().tintColor = UIColor.white

    UIBarButtonItem.appearance().tintColor = UIColor.white
}

... pour AppDelegate, à l'échelle de l'application, dans Objective-C:

if (@available(iOS 13, *)) {
    UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
    [appearance configureWithOpaqueBackground];
    appearance.backgroundColor = UIColor.whiteColor;
    appearance.titleTextAttributes = titleAttributes;

    UIBarButtonItemAppearance *buttonAppearance = [[UIBarButtonItemAppearance alloc] init];
    buttonAppearance.normal.titleTextAttributes = barButtonItemAttributes;
    appearance.buttonAppearance = buttonAppearance;

    UINavigationBar.appearance.standardAppearance = appearance;
    UINavigationBar.appearance.scrollEdgeAppearance = appearance;
    UINavigationBar.appearance.compactAppearance = appearance;

    [[UINavigationBar appearance] setTintColor:UIColor.blackColor];
} else {
    [[UINavigationBar appearance] setBarTintColor:UIColor.whiteColor];
    [[UINavigationBar appearance] setTintColor:UIColor.blackColor];
    [[UINavigationBar appearance] setTranslucent:false];
    [[UINavigationBar appearance] setTitleTextAttributes: titleAttributes];
    [[UIBarButtonItem appearance] setTitleTextAttributes:barButtonItemAttributes forState:UIControlStateNormal];
}
Stu Carney
la source
Merci, c'est une bonne réponse! , sur iOS 13, Apple a ajouté UINavigationBarAppearance()et sans raison sur l'ancien Xcode, nous n'avons pas dû en dépendre, mais depuis Xcode 11.4, il doit utiliser UINavigationBarAppearance()ou la couleur du titre sera toujours de couleur noire.
Basil
appearance.largeTitleTextAttributespour les grands titres.
Skoua
Cela fonctionne très bien et merci !, Y a-t-il une façon de le faire universellement depuis l'AppDelegate?
slicerdicer
@slicerdicer - Ouais! Voir ma réponse mise à jour, pour un exemple. À votre santé.
Stu Carney
1
@Richard - Je viens d'ajouter la réponse pour Objective-C. Désolé, je n'ai pas vu votre commentaire jusqu'à aujourd'hui.
Stu Carney
14

Sur le storyboard, pour votre contrôleur de navigation, changez la "teinte de la barre" en sa valeur "par défaut", puis sur votre code, vous pouvez le changer comme vous le feriez normalement.

Sudhakar Varma
la source
3
Meilleure réponse. Vraiment.
Vladimir Prigarin
2
C'est la bonne façon
Hugo
1
Meilleure période de réponse.
shadowsheep
2
@ JCutting8 yup, c'est vrai. Mais avec Xcode 11.4 si vous ne définissez pas la couleur par défaut dans le storyboard, la modifier par programme ne fonctionne pas. Je ne sais pas si c'est un problème ou non.
shadowsheep
1
Ceci est une magie!
ekashking
6

Je ne sais pas si c'est un bug ou non.

Nous l'avons corrigé en réglant le "Style de la barre d'état" sur un contenu sombre ou clair dans le cadre du projet. Cela forcera la couleur du texte de la barre d'état d'une certaine manière plutôt que d'être déterminée en fonction des appareils en mode clair ou sombre.

En outre, vous devez définir la valeur "Afficher l'apparence de la barre d'état basée sur le contrôleur" sur "NON" dans votre Info.plist. sans cette valeur, le "style de la barre d'état" sera remplacé.

Créez ensuite un contrôleur de navigation personnalisé et implémentez-le dans vos storyboards.

class CustomNavigationController: UINavigationController {

 override func viewDidLoad() {
    super.viewDidLoad()
    setNavBar()
 }

 func setNavBar() {
    if #available(iOS 13.0, *) {
        let appearance = UINavigationBarAppearance()
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = UIColor.blue
        appearance.titleTextAttributes = [.foregroundColor: UIColor.yellow]
        self.navigationBar.standardAppearance = appearance
        self.navigationBar.scrollEdgeAppearance = appearance
        self.navigationBar.compactAppearance = appearance
    } else {
        self.navigationBar.barTintColor = UIColor.blue
        self.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.yellow]
    }
  }
}

* Les couleurs sont définies pour que vous puissiez les voir fonctionner clairement.

J'ai trouvé qu'il était préférable de définir le code dans ViewDidLoad plutôt que ViewDidAppear parce que mes couleurs n'étaient pas définies lors du chargement initial, uniquement après la navigation et le rechargement.

J'ai également constaté que ce problème pouvait être lié à la "teinte de la barre" d'une barre de navigation. lorsque nous avons essayé de le résoudre pour la première fois, nous avons défini la "teinte de la barre" par défaut et cela a semblé résoudre l'erreur également. Cependant, cela nous a empêché d'obtenir la couleur d'arrière-plan NavBar comme nous le voulions. Donc, dans mes storyboards, je me suis assuré de définir cette valeur par défaut juste pour faire bonne mesure.

J'espère que cela aide

jameseronious
la source
Cela fonctionne. Il semble que cela ne fasse que définir le style global qui ne fonctionne pas.
Mongo
def un bug sur la fin de la pomme. ne peut s'empêcher de casser des choses>. <
Michael McKenna
2

pas besoin de workaround.it est un bogue dans Xcode Interface Builder. Mise à jour d'Apple pour Xcode 11.4.1

des notes de version du développeur Apple

Générateur d'interface

Correction d'un problème en raison duquel certaines propriétés d'apparence UINavigationBar définies dans le storyboard et les documents XIB étaient ignorées lors de la construction avec Xcode 11.4. (60883063) (FB7639654)

https://developer.apple.com/documentation/xcode_release_notes/xcode_11_4_1_release_notes

NinjaDeveloper
la source
0

Semblable à la réponse de Stu Carney le 25/03, j'ai ajouté quelques détails de mise en œuvre supplémentaires.

Créez une sous-classe de UINavigationController . Ajoutez les éléments suivants pour afficherWillAppear:

let isDarkMode = UserDefaults.standard.bool(forKey: "DarkMode")
let titleColor: UIColor = isDarkMode ? .white : .black
let navBarColor: UIColor = isDarkMode ? .black : .white
let tintColor: UIColor = isDarkMode ? .yellow : .red  //back button text and arrow color, as well as right bar button item

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = navBarColor
    appearance.titleTextAttributes = [.foregroundColor: titleColor]
    appearance.largeTitleTextAttributes = [.foregroundColor: titleColor]

    self.navigationBar.standardAppearance = appearance
    self.navigationBar.scrollEdgeAppearance = appearance
    self.navigationBar.compactAppearance = appearance // For iPhone small navigation bar in landscape.

    self.navigationBar.tintColor = tintColor //changes back button text and arrow color, as well as right bar button item
} else {
    self.navigationBar.barTintColor = navBarColor
    self.navigationBar.tintColor = tintColor
    self.navigationBar.titleTextAttributes = [.foregroundColor: titleColor]
    self.navigationBar.largeTitleTextAttributes = [.foregroundColor: titleColor]
}

Ensuite , passer outre preferredStatusBarStyle :

override var preferredStatusBarStyle: UIStatusBarStyle {
    let isDarkMode = UserDefaults.standard.bool(forKey: "DarkMode")
    return isDarkMode ? .lightContent : .default
}

Si vous souhaitez mettre à jour la barre de navigation et la barre d'état de manière dynamique, comme à partir d'une méthode UISwitch IBAction ou d'un sélecteur, ajoutez ce qui suit:

navigationController?.loadView()
navigationController?.topViewController?.setNeedsStatusBarAppearanceUpdate()

Veillez également à définir toutes vos barres de navigation et boutons de barre sur les couleurs par défaut dans IB. Xcode semble avoir un bogue où les couleurs IB remplacent les couleurs définies par programmation.

Josh R
la source
0

Dans mon cas, après avoir mis à niveau Xcode de 11.3 à 11.4, ce bug s'est produit. Je dois donc changer mon code pour souffler afin de mettre une image en arrière-plan dans la barre de navigation.

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    let backgroundImage = UIImage(named: "{NAVBAR_IMAGE_NAME}")?.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch)
    appearance.backgroundImage = backgroundImage
    self.navigationController?.navigationBar.compactAppearance = appearance
    self.navigationController?.navigationBar.standardAppearance = appearance
    self.navigationController?.navigationBar.scrollEdgeAppearance = appearance        
} else {
    self.navigationController?.navigationBar.barTintColor = Utils.themeColor
    let backgroundImage = UIImage(named: "{NAVBAR_IMAGE_NAME}")?.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch)
    self.navigationController?.navigationBar.setBackgroundImage(backgroundImage, for: .default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
}
Reza Dehnavi
la source