Xcode 11.4. Tytuł nawigacji Kolor zniknął CZARNY z scenorysu

55

Niedawno zaktualizowałem swój Xcode do 11.4. Kiedy uruchamiam aplikację na urządzeniu, zauważyłem, że wszystkie tytuły moich elementów nawigacyjnych stały się całkowicie czarne po ustawieniu z scenorysu. wprowadź opis zdjęcia tutaj

Nie możesz zmienić żadnego z kodu, następujący wiersz kodu już nie działa

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

Sprawiam, że działa tylko przy użyciu UINavigationBarAppearance na iOS 13

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

Czy ktoś może mi wyjaśnić, dlaczego? To kluczowy błąd, czy jakaś nowa ukryta funkcja?

Tudor Popa
źródło
3
Ten sam problem tutaj i nie mogę nic zrobić, aby to naprawić. Myślę, że to błąd: /
Jordan Favray
Jabłko. Ugh Naprawdę?
Daniel
spróbuj tego jeden stackoverflow.com/a/61003557/3887987
Amrit Tiwari
jest to Xcode
Code

Odpowiedzi:

36

Naprawiłem to, używając zamiast tego UINavigationBarAppearance z: Dostosowywanie paska nawigacyjnego aplikacji

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

Uwaga: podklasowałem UINavigationController , i to zostało wywołane z przesłonięcia viewWillAppear .

... lub dla AppDelegate , dla całej aplikacji:

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
}

... dla AppDelegate, dla całej aplikacji, w 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
źródło
Dziękuję, to poprawna odpowiedź! , dodano UINavigationBarAppearance()do iOS 13 Apple i bez żadnego powodu na starym Xcode nie byliśmy uzależnieni od niego, ale od Xcode 11.4 musi go używać UINavigationBarAppearance()lub kolor tytułu będzie zawsze czarny.
Basil
appearance.largeTitleTextAttributesdla dużych tytułów.
Skoua
Działa to świetnie i dziękuję !, Czy jest tak, aby zrobić to uniwersalnie z AppDelegate?
krajalnica
@slicerdicer - Tak! Zobacz moją zaktualizowaną odpowiedź, na przykład. Twoje zdrowie.
Stu Carney
1
@Richard - Właśnie dodałem odpowiedź dla Objective-C. Przepraszam, nie widziałem twojego komentarza aż do dzisiaj.
Stu Carney,
14

W serii ujęć dla kontrolera nawigacyjnego zmień wartość „Odcień paska” na wartość „Domyślna”, a następnie w kodzie możesz go zmienić w normalny sposób.

Sudhakar Varma
źródło
3
Najlepsza odpowiedź. Naprawdę.
Vladimir Prigarin
2
To jest właściwy sposób
Hugo,
1
Najlepszy okres odpowiedzi.
shadowsheep
2
@ JCutting8 tak, zgadza się. Ale w Xcode 11.4, jeśli nie ustawisz domyślnego koloru w serii ujęć, programowa zmiana go nie zadziała. Nie wiem, czy to problem, czy nie.
shadowsheep
1
To jest magia!
ekashking
6

Nie jestem pewien, czy to błąd, czy nie.

Naprawiliśmy to, ustawiając „Styl paska stanu” na ciemną lub jasną zawartość w ustawieniach projektu. To wymusi kolor tekstu paska stanu w określony sposób, a nie zostanie określony na podstawie urządzeń w trybie jasnym lub ciemnym.

Ponadto należy ustawić wartość „Wyświetl wygląd paska stanu kontrolera” na „NIE” w swoim Info.plist. bez tej wartości „Styl paska stanu” zostanie zastąpiony.

Następnie utwórz niestandardowy kontroler nawigacji i zaimplementuj go w swoich scenorysach.

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

* Kolory są ustawione, dzięki czemu można je wyraźnie zobaczyć.

Odkryłem, że lepiej było ustawić kod w ViewDidLoad niż ViewDidAppear, ponieważ moje kolory nie były ustawiane przy początkowym ładowaniu, tylko po przejściu wstecz i ponownym załadowaniu.

Odkryłem również, że ten problem może być związany z „Bar Tint” paska nawigacyjnego. kiedy po raz pierwszy próbowaliśmy go rozwiązać, ustawiliśmy „Bar Tint” na domyślny, co również wydawało się rozwiązać błąd. Jednak sprawiło, że nie mogliśmy uzyskać pożądanego koloru tła NavBar. Więc w moich scenariuszach upewniłem się, że dla tej wartości ustawiłem wartość domyślną.

Mam nadzieję, że to pomoże

jameseronious
źródło
To działa. Wydaje się, że to po prostu ustawienie globalnego stylu, który nie działa.
Mongo
def błąd na końcu jabłka. nic nie poradzę, ale psujesz rzeczy. <
Michael McKenna,
2

nie ma potrzeby obejścia tego problemu. to błąd w Xcode Interface Builder. Aktualizacja wydania Apple dla Xcode 11.4.1

z informacji o wersji dla programistów Apple

Konstruktor interfejsów

Naprawiono błąd, który powodował, że niektóre właściwości wyglądu UINavigationBar ustawione w scenorysie i dokumentach XIB były ignorowane podczas budowania z Xcode 11.4. (60883063) (FB7639654)

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

NinjaDeveloper
źródło
0

Podobnie do odpowiedzi Stu Carney z 3/25, dodałem jeszcze kilka szczegółów implementacji.

Utwórz podklasę UINavigationController . Dodaj następujące elementy, aby wyświetlićWillAppear:

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

Następnie zastąp preferowaneStatusBarStyle :

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

Jeśli chcesz dynamicznie aktualizować pasek nawigacyjny i pasek stanu, jak w przypadku metody UISwitch IBAction lub metody wyboru, dodaj:

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

Pamiętaj też, aby ustawić wszystkie paski nawigacji i przyciski paska na domyślne kolory w IB. Wygląda na to, że Xcode ma błąd polegający na tym, że kolory IB zastępują kolory ustawione programowo.

Josh R.
źródło
0

W moim przypadku po aktualizacji Xcode z 11.3 do 11.4 ten błąd wystąpił. Muszę więc zmienić kod, by go wysadził, aby ustawić obraz jako tło na pasku nawigacyjnym.

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
źródło