Xcode 11.4. Il titolo di navigazione Colore è NERO dallo storyboard


55

Di recente ho aggiornato il mio Xcode alla 11.4. Quando eseguo l'app sul dispositivo, ho notato che tutti i titoli dei miei elementi di navigazione sono diventati completamente neri quando sono stati impostati dallo storyboard. inserisci qui la descrizione dell'immagine

Non è possibile modificare né dal codice, la seguente riga di codice non funziona più

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

Lo faccio funzionare solo con alcuni elementi 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]
    }

Qualcuno può spiegarmi perché ??? Questo è un bug cruciale o qualche nuova funzionalità nascosta?


3
Lo stesso problema qui e non trovo nulla da fare per correggere questo. Penso che sia un bug: /
Jordan Favray il

Mela. Uggh. Veramente?
Daniel


è Xcode
Code

Risposte:



36

Questo mi ha risolto, usando invece UINavigationBarAppearance da: Personalizzare la barra di navigazione della tua 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]
}

Nota: ho eseguito la sottoclasse di UINavigationController e questo è stato chiamato dall'override di viewWillAppear .

... o per AppDelegate , a livello di app:

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
}

... per AppDelegate, a livello di app, 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];
}

Grazie, questa è una risposta corretta! , su iOS 13 Apple ha aggiunto UINavigationBarAppearance()e per nessun motivo sul vecchio Xcode non abbiamo dovuto dipendere da esso, ma dal momento che Xcode 11.4 deve usare UINavigationBarAppearance()o il colore del titolo sarà sempre di colore nero.
Basilio

appearance.largeTitleTextAttributesper titoli di grandi dimensioni.
Skoua,

Funziona benissimo e grazie! C'è un modo per farlo universalmente dall'AppDelegate?
slicerdicer

@slicerdicer - Yep! Vedi la mia risposta aggiornata, per un esempio. Saluti.
Stu Carney,

1
@Richard - Ho appena aggiunto la risposta per Objective-C. Mi dispiace, non ho visto il tuo commento fino ad oggi.
Stu Carney,

14

Sullo storyboard, per il tuo controller di navigazione, modifica "Tinta barra" sul valore "Predefinito", quindi sul tuo codice puoi cambiarlo come faresti normalmente.


3
Migliore risposta. Veramente.
Vladimir Prigarin,

2
Questo è il modo giusto
Hugo

1
Periodo migliore anwer❗️.
shadowsheep

2
@ JCutting8 sì, esatto. Ma con Xcode 11.4 se non si imposta il colore predefinito nello storyboard, modificandolo a livello di codice non funziona. Non so se questo è un problema o no.
shadowsheep

1
Questa è una magia!
ekashking

6

Non sono sicuro se si tratta di un bug o no.

Il modo in cui l'abbiamo risolto è impostando lo "Stile barra di stato" su contenuto scuro o chiaro nell'impostazione del progetto. Ciò forzerà il colore del testo della barra di stato in un certo modo piuttosto che essere determinato in base ai dispositivi che si trovano in modalità chiaro o scuro.

Inoltre, è necessario impostare il valore "Visualizza aspetto della barra di stato basata sul controller" su "NO" nel proprio Info.plist. senza quel valore lo "Stile barra di stato" verrà ignorato.

Quindi crea un controller di navigazione personalizzato e implementalo negli storyboard.

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

* I colori sono impostati in modo da poterli vedere chiaramente funzionanti.

Ho scoperto che era meglio impostare il codice in ViewDidLoad piuttosto che ViewDidAppear perché i miei colori non venivano impostati sul caricamento iniziale, solo dopo essere tornati indietro e ricaricati.

Ho anche scoperto che questo problema potrebbe essere legato alla "Bar Tint" di un NavBar. quando stavamo provando per la prima volta a risolverlo, abbiamo impostato "Bar Tint" sul valore predefinito e anche questo sembrava risolvere l'errore. Tuttavia, è stato creato in modo da non poter ottenere il colore di sfondo di NavBar come desiderato. Quindi nei miei storyboard mi sono assicurato di impostare questo valore come predefinito solo per una buona misura.

Spero che sia d'aiuto


Questo funziona. Sembra che stia semplicemente impostando lo stile globale che non funziona.
Mongo,

def un bug all'estremità di apple. non posso fare a meno di rompere le cose>. <
Michael McKenna il

2

non c'è bisogno di workaround.it è un bug in Xcode Interface Builder. Aggiornamento della versione Apple per Xcode 11.4.1

dalle note di rilascio degli sviluppatori Apple

Interface Builder

Risolto il problema per cui alcune proprietà dell'aspetto di UINavigationBar impostate nello storyboard e nei documenti XIB venivano ignorate durante la creazione con Xcode 11.4. (60883063) (FB7639654)

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


0

Simile alla risposta di Stu Carney del 3/25, ho aggiunto alcuni dettagli di implementazione.

Creare una sottoclasse di UINavigationController . Aggiungi quanto segue per viewWillAppear:

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

Quindi eseguire l'override diStatusBarStyle preferito :

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

Se si desidera aggiornare dinamicamente la barra di navigazione e la barra di stato, come da un UISwitch IBAction o un metodo di selezione, aggiungere quanto segue:

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

Inoltre, assicurati di impostare tutte le barre di navigazione e i pulsanti delle barre sui colori predefiniti in IB. Xcode sembra avere un bug in cui i colori IB sovrascrivono i colori impostati programmaticamente.


0

Nel mio caso, dopo aver aggiornato Xcode da 11.3 a 11.4 questo errore si è verificato. Quindi devo cambiare il mio codice per esplodere per impostare un'immagine come sfondo nella barra di navigazione.

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()
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.