Xcode 11.4. Die Titelfarbe der Navigation wurde vom Storyboard SCHWARZ

55

Ich habe kürzlich meinen Xcode auf 11.4 aktualisiert. Wenn ich die App auf dem Gerät ausführe, ist mir aufgefallen, dass alle Titel meiner Navigationselemente beim Festlegen über das Storyboard vollständig schwarz wurden. Geben Sie hier die Bildbeschreibung ein

Sie können weder den Code ändern, die folgende Codezeile funktioniert nicht mehr

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

Ich mache es nur mit einigen iOS 13 Sachen 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]
    }

Kann mir jemand erklären warum ??? Dies ist ein entscheidender Fehler oder eine neue versteckte Funktion?

Tudor Popa
quelle
3
Das gleiche Problem hier und ich finde nichts zu tun, um dies zu korrigieren. Ich denke, es ist ein Fehler: /
Jordan Favray
Apfel. Uggh. "Ja wirklich?"
Daniel
Versuchen Sie dies einen stackoverflow.com/a/61003557/3887987
Amrit Tiwari
Es ist Xcode Interface Builder Bug Update XCode auf 11.4.1
NinjaDeveloper

Antworten:

36

Dies wurde für mich behoben, indem stattdessen UINavigationBarAppearance verwendet wurde: Anpassen der Navigationsleiste Ihrer App

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]
}

Hinweis: Ich habe UINavigationController in Unterklassen unterteilt , und dies wurde beim Überschreiben von viewWillAppear aufgerufen .

... oder für AppDelegate app-weit:

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
}

... für AppDelegate, App-weit, in 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
quelle
Danke, das ist eine richtige Antwort! , unter iOS 13 hat Apple hinzugefügt UINavigationBarAppearance()und ohne Grund auf alten Xcode haben wir uns nicht darauf verlassen, aber da Xcode 11.4 verwendet werden muss, UINavigationBarAppearance()wird die Titelfarbe immer Schwarz sein.
Basil
appearance.largeTitleTextAttributesfür große Titel.
Skoua
Das funktioniert super und danke! Gibt es überhaupt eine universelle Möglichkeit, dies über das AppDelegate zu tun?
Slicerdicer
@slicerdicer - Ja! Ein Beispiel finden Sie in meiner aktualisierten Antwort. Prost.
Stu Carney
1
@ Richard - Ich habe gerade die Antwort für Objective-C hinzugefügt. Entschuldigung, ich habe Ihren Kommentar bis heute nicht gesehen.
Stu Carney
14

Ändern Sie im Storyboard für Ihren Navigationscontroller die "Balkentönung" in den Wert "Standard". In Ihrem Code können Sie sie dann wie gewohnt ändern.

Sudhakar Varma
quelle
3
Beste Antwort. Ja wirklich.
Vladimir Prigarin
2
Dies ist der richtige Weg
Hugo
1
Beste Antwortzeit.
Shadowsheep
2
@ JCutting8 yup, das stimmt. Wenn Sie jedoch mit Xcode 11.4 nicht die Standardfarbe im Storyboard festlegen und diese programmgesteuert ändern, funktioniert dies nicht. Ich weiß nicht, ob dies ein Problem ist oder nicht.
Shadowsheep
1
Das ist eine Magie!
Ekashking
6

Ich bin mir nicht sicher, ob es ein Fehler ist oder nicht.

Wir haben dies behoben, indem wir den "Statusleistenstil" in der Projekteinstellung entweder auf dunklen oder hellen Inhalt eingestellt haben. Dadurch wird die Textfarbe der Statusleiste auf eine bestimmte Weise erzwungen, anstatt anhand der Geräte im Hell- oder Dunkelmodus festgelegt zu werden.

Außerdem müssen Sie in Ihrer Info.plist den Wert "Erscheinungsbild der Controller-basierten Statusleiste anzeigen" auf "NEIN" setzen. ohne diesen Wert wird der "Statusleistenstil" überschrieben.

Erstellen Sie als Nächstes einen benutzerdefinierten Navigationscontroller und implementieren Sie ihn in Ihre 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]
    }
  }
}

* Die Farben sind so eingestellt, dass Sie sehen können, dass sie klar funktionieren.

Ich fand es besser, den Code in ViewDidLoad anstatt in ViewDidAppear festzulegen, da meine Farben beim ersten Laden nicht festgelegt wurden, sondern erst nach dem Zurücknavigieren und erneuten Laden.

Ich habe auch festgestellt, dass dieses Problem möglicherweise mit dem "Bar Tint" einer NavBar zusammenhängt. Als wir zum ersten Mal versuchten, das Problem zu beheben, haben wir die "Balkentönung" auf den Standardwert gesetzt, und das schien auch den Fehler zu beheben. Es hat es jedoch so gemacht, dass wir nicht die NavBar-Hintergrundfarbe bekommen konnten, die wir wollten. Daher habe ich in meinen Storyboards sichergestellt, dass dieser Wert nur aus gutem Grund auf den Standardwert gesetzt wird.

Ich hoffe es hilft

jameseronious
quelle
Das funktioniert. Es scheint, als würde nur der globale Stil festgelegt, der nicht funktioniert.
Mongo
def einen Fehler am Ende des Apfels. kann nicht anders, als Dinge zu zerbrechen>. <
Michael McKenna
2

Die Problemumgehung ist nicht erforderlich. Es handelt sich um einen Fehler im Xcode Interface Builder. Apple Release Update für Xcode 11.4.1

aus den Versionshinweisen für Apple-Entwickler

Interface Builder

Es wurde ein Problem behoben, durch das einige in Storyboard- und XIB-Dokumenten festgelegte Eigenschaften der UINavigationBar-Darstellung beim Erstellen mit Xcode 11.4 ignoriert wurden. (60883063) (FB7639654)

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

NinjaDeveloper
quelle
0

Ähnlich wie bei Stu Carneys Antwort vom 25. März habe ich einige weitere Implementierungsdetails hinzugefügt.

Erstellen Sie eine Unterklasse von UINavigationController . Fügen Sie viewWillAppear Folgendes hinzu:

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]
}

Dann überschreiben preferredStatusBarStyle :

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

Wenn Sie die Navigationsleiste und die Statusleiste dynamisch aktualisieren möchten, z. B. über eine UISwitch-IBAction oder eine Auswahlmethode, fügen Sie Folgendes hinzu:

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

Stellen Sie außerdem sicher, dass alle Navigationsleisten und Balkenschaltflächen in IB auf die Standardfarben eingestellt sind. Xcode scheint einen Fehler zu haben, bei dem die IB-Farben die programmgesteuert festgelegten Farben überschreiben.

Josh R.
quelle
0

In meinem Fall trat dieser Fehler auf, nachdem ich Xcode von 11.3 auf 11.4 aktualisiert hatte. Also muss ich meinen Code ändern, um zu blasen, um ein Bild als Hintergrund in der Navigationsleiste festzulegen.

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
quelle