Xcode 11.4. Color del título de la navegación NEGRO del storyboard

55

Recientemente actualicé mi Xcode a 11.4. Cuando ejecuto la aplicación en el dispositivo, noté que todos los títulos de mis elementos de navegación se volvieron completamente negros cuando se configuraron desde el guión gráfico. ingrese la descripción de la imagen aquí

No puede cambiar ni desde el código, la siguiente línea de código ya no funciona

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

Solo lo hago funcionar usando algunas cosas de 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]
    }

¿Alguien puede explicarme por qué? Este es un error crucial, o alguna nueva característica oculta?

Tudor Popa
fuente
3
El mismo problema aquí y no encuentro nada que hacer para corregir esto. Creo que es un error: /
Jordan Favray
Manzana. Uggh De Verdad?
Daniel
pruebe este stackoverflow.com/a/61003557/3887987
Amrit Tiwari
es el Xcode de actualización de
errores del

Respuestas:

36

Esto me lo arregló, usando UINavigationBarAppearance en su lugar, desde: Personalizar la barra de navegación de su aplicación

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: Subclasifiqué UINavigationController , y esto se llamó desde la anulación de viewWillAppear .

... o para AppDelegate , en toda la aplicación:

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
}

... para AppDelegate, en toda la aplicación, en 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
fuente
¡Gracias, esta es una respuesta correcta! , en iOS 13 Apple agregó UINavigationBarAppearance()y sin ninguna razón en el antiguo Xcode no teníamos que depender de él, pero desde Xcode 11.4 debe usar UINavigationBarAppearance()o el color del título siempre será de color negro.
Basilio
appearance.largeTitleTextAttributespara grandes títulos
Skoua
¡Esto funciona muy bien y gracias! ¿Hay alguna forma de hacerlo universalmente desde AppDelegate?
slicerdicer
@slicerdicer - ¡Sí! Vea mi respuesta actualizada, para un ejemplo. Salud.
Stu Carney
1
@ Richard - Acabo de agregar la respuesta para Objective-C. Lo siento, no vi tu comentario hasta hoy.
Stu Carney
14

En el guión gráfico, para su Controlador de navegación, cambie el "Tinte de barra" a su valor "Predeterminado", luego, en su código, puede cambiarlo como lo haría normalmente.

Sudhakar Varma
fuente
3
La mejor respuesta. De Verdad.
Vladimir Prigarin
2
Esta es la forma correcta
Hugo
1
Mejor período de anwer❗️.
shadowsheep
2
@ JCutting8 sí, eso es correcto. Pero con Xcode 11.4 si no configura el color predeterminado en el guión gráfico, cambiarlo programáticamente no funciona. No sé si esto es un problema o no.
shadowsheep
1
Esto es una magia!
Ekashking
6

No estoy seguro si es un error o no.

La forma en que lo arreglamos es configurando el "Estilo de barra de estado" en contenido oscuro o claro en la configuración del proyecto. Esto forzará el color del texto de la barra de estado de una determinada manera en lugar de determinarse en función de los dispositivos en modo claro u oscuro.

Además, debe establecer el valor "Ver la apariencia de la barra de estado basada en el controlador" en "NO" en su Info.plist. sin ese valor, se anulará el "Estilo de barra de estado".

A continuación, cree un controlador de navegación personalizado e impleméntelo en sus guiones gráficos.

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

* Los colores están configurados para que pueda verlos claramente trabajando.

Descubrí que era mejor configurar el código en ViewDidLoad en lugar de ViewDidAppear porque mis colores no se configuraban en la carga inicial, solo después de navegar hacia atrás y volver a cargar.

También descubrí que este problema podría estar relacionado con el "Tinte de barra" de una barra de navegación. cuando intentamos resolverlo por primera vez, configuramos el "Tinte de barra" por defecto y eso también pareció resolver el error. Sin embargo, lo hizo para que no pudiéramos obtener el color de fondo NavBar que queríamos. Entonces, en mis guiones gráficos, me aseguré de establecer este valor por defecto solo por si acaso.

Espero eso ayude

jameseronious
fuente
Esto funciona Parece que solo está configurando el estilo global que no funciona.
Mongo
Definir un error en el final de Apple. no puedo evitar romper cosas>. <
Michael McKenna
2

no es necesario el workaround.it es un error en Xcode Interface Builder. Actualización de lanzamiento de Apple para Xcode 11.4.1

de las notas de la versión para desarrolladores de Apple

Interface Builder

Se solucionó un problema que causaba que algunas propiedades de apariencia UINavigationBar establecidas en el guión gráfico y los documentos XIB se ignoraran al compilar con Xcode 11.4. (60883063) (FB7639654)

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

NinjaDeveloper
fuente
0

Similar a la respuesta de Stu Carney el 25/3, agregué algunos detalles más de implementación.

Cree una subclase de UINavigationController . Agregue lo siguiente para verWillAppear:

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

A continuación, anule preferredStatusBarStyle :

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

Si desea actualizar la barra de navegación y la barra de estado dinámicamente, como desde un método UISwitch IBAction o selector, agregue lo siguiente:

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

Además, asegúrese de configurar todas sus barras de navegación y botones de barra con los colores predeterminados en IB. Xcode parece tener un error en el que los colores IB anulan los colores establecidos programáticamente.

Josh R
fuente
0

En mi caso, después de actualizar Xcode de 11.3 a 11.4, se produjo este error. Entonces tengo que cambiar mi código para soplar para establecer una imagen como fondo en la barra de navegación.

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
fuente