簡體   English   中英

iOS13狀態欄背景顏色與大文本模式下的導航欄不同

[英]In iOS13 the status bar background colour is different from the navigation bar in large text mode

問題演示

重現問題的前提條件:

  1. Xcode 11 beta + iOS 13(2019 年 6 月 12 日之前的最新版本)
  2. 導航欄處於大文本模式
  3. 指定導航欄的顏色。

在真實設備中,狀態欄將保持為白色,位於綠色導航欄上方。

我嘗試過的解決方案:

  1. 恢復到 iOS12 就可以解決,但最終還是會遇到 iOS13...
  2. 禁用大文本模式將解決它...
  3. 隱藏狀態欄將修復它,但它會導致狀態文本與導航欄項目重疊。

有任何想法嗎? 感謝任何幫助。

這里不需要任何技巧或時髦。 關鍵是定義所需的外觀並在導航欄的standardAppearance和它的scrollEdgeAppearance上設置此值。 我在整個應用程序的基本導航控制器子類的 init 中有以下內容:

if #available(iOS 13.0, *) {
    let navBarAppearance = UINavigationBarAppearance()
    navBarAppearance.configureWithOpaqueBackground()
    navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
    navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
    navBarAppearance.backgroundColor = <insert your color here>
    navigationBar.standardAppearance = navBarAppearance
    navigationBar.scrollEdgeAppearance = navBarAppearance
}

在此處輸入圖像描述

如果問題是您想在顯示大標題時為導航欄提供顏色,請使用新的 UINavigationBarAppearance 類。

let app = UINavigationBarAppearance()
app.backgroundColor = .blue
self.navigationController?.navigationBar.scrollEdgeAppearance = app

在 iOS 13 上,根據 Apple 人機界面指南,使用大標題的導航欄具有透明顏色。 在此處查看更多信息:

在 iOS 13 及更高版本中,大標題導航欄默認不包含背景材質或陰影。 此外,隨着人們開始滾動內容,大標題會轉換為標准標題

通用代碼

let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
navBarAppearance.backgroundColor = // your color
navBarAppearance.shadowImage = nil // line
navBarAppearance.shadowColor = nil // line
UINavigationBar.appearance(whenContainedInInstancesOf: [UINavigationController.self]).standardAppearance = navBarAppearance
UINavigationBar.appearance(whenContainedInInstancesOf: [UINavigationController.self]).scrollEdgeAppearance = navBarAppearance

我的導航欄擴展,iOS 13 Swift 5

extension UIViewController {
func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
    if #available(iOS 13.0, *) {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.backgroundColor = backgoundColor

        navigationController?.navigationBar.standardAppearance = navBarAppearance
        navigationController?.navigationBar.compactAppearance = navBarAppearance
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance

        navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.tintColor = tintColor
        navigationItem.title = title

    } else {
        // Fallback on earlier versions
        navigationController?.navigationBar.barTintColor = backgoundColor
        navigationController?.navigationBar.tintColor = tintColor
        navigationController?.navigationBar.isTranslucent = false
        navigationItem.title = title
    }
}}

如何使用:

configureNavigationBar(largeTitleColor: .yourColor, backgoundColor: .yourColor, tintColor: .yourColor, title: "YourTitle", preferredLargeTitle: true)

如果你想要輕量的內容,在 info.plist 中將基於 ViewController 的狀態欄......設置為 NO

如果您不希望 largeTitles 將其設置為 false

在 iOS 13 上測試,希望對您有所幫助:)

Objective C 解決方案和 iOS 13

UINavigationBarAppearance* navBarAppearance = [self.navigationController.navigationBar standardAppearance];
        [navBarAppearance configureWithOpaqueBackground];
        navBarAppearance.titleTextAttributes = @{NSForegroundColorAttributeName:TitleColor};
        navBarAppearance.largeTitleTextAttributes = @{NSForegroundColorAttributeName: TitleColor};
        navBarAppearance.backgroundColor = TopColor;
        self.navigationController.navigationBar.standardAppearance = navBarAppearance;
        self.navigationController.navigationBar.scrollEdgeAppearance = navBarAppearance;

如果要刪除導航欄下方的下划線

if #available(iOS 13.0, *) {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
        navBarAppearance.backgroundColor = <yourColor>
        navBarAppearance.backgroundImage = UIImage()
        navBarAppearance.shadowImage = UIImage()
        navBarAppearance.shadowColor = .clear
        self.navigationController?.navigationBar.standardAppearance = navBarAppearance
        self.navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
   
    }

對於 iOS 13,我遇到了條形陰影線出現的問題。 將 Bars 陰影圖像設置為nil解決了這個問題。

func configureNavigation() {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.myColor,
                                                     .font: UIFont(name: "MyFont", size: 42)!]
        navBarAppearance.backgroundColor = .white
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
    }

帶陰影的圖像

func configureNavigation() {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.myColor,
                                                     .font: UIFont(name: "MyFont", size: 42)!]
        navBarAppearance.backgroundColor = .white
        navBarAppearance.shadowColor = nil
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
    }

沒有陰影的圖像

完全可行的代碼:

 let navigationBarAppearace = UINavigationBar.appearance()
    navigationBarAppearace.tintColor = .tintColor
    navigationBarAppearace.barTintColor = .barTintColor
    navigationBarAppearace.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.tintColor]

if #available(iOS 13.0, *) {
  let navBarAppearance = UINavigationBarAppearance()
  navBarAppearance.configureWithOpaqueBackground()
  navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.tintColor]
  navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.tintColor]
  navBarAppearance.backgroundColor = <insert your color here>
  navigationBarAppearace.standardAppearance = navBarAppearance // have a look here ;)
  navigationBar.scrollEdgeAppearance = navBarAppearance
}

祝大家好運,和平!

感謝邁克和漢斯的回答。 我的案例是半透明狀態欄和 alpha 0.5 的導航欄。 iOS13 看起來很復雜。 以下是我的測試結果,如果您希望兩者都透明,則可以使用。

if #available(iOS 13.0, *) {
                let navBarAppearance = UINavigationBarAppearance()
                // This only set top status bar as transparent, not the nav bar.
                navBarAppearance .configureWithTransparentBackground()
                // This set the color for both status bar and nav bar(alpha 1).
                navBarAppearance.backgroundColor = UIColor.red.withAlphaComponent(0.5)
                navigationController?.navigationBar.standardAppearance = navBarAppearance
                navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
                // Nav bar need sets to translucent for both nav bar and status bar to be translucent.
                navigationController?.navigationBar.isTranslucent = true
                // // Need to reset nav bar's color to make it clear to display navBarAppearance's color
                navigationController?.navigationBar.backgroundColor = UIColor.clear
               } 

在將我的一個應用程序更新為更兼容 iOS 13 時,我遇到了類似的問題。 正如Hans上面提到的,大標題默認是透明的。 如果您像我一樣是 Storyboard 的重度用戶,那么側欄中還有另一個設置很容易打開。

如果您單擊故事板中的導航欄,通常默認選擇Navigation Item ,並且您不會獲得任何自定義選項。 選擇其上方的Navigation Bar選項,然后您可以在右側的檢查器中選擇您想要的任何自定義背景顏色。

在此處輸入圖像描述

我發現使用故事板你必須偽造導航欄(假設你的綠色是不透明的,只適用於不透明的導航欄)。 我發現最好的方法是創建一個適合安全區域插圖的占位符視圖(紫色),然后在導航欄(青色/藍色)后面添加一個假視圖,即剩余高度。 適用於我的項目,但是是的,這有點麻煩。 Xcode 11 beta 4 的屏幕截圖顯示了狀態欄破解所需的約束

編輯:這主要用於 LaunchScreen.storyboard,您不能在其中使用自定義視圖控制器類。

斯威夫特 5

 override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) let userInterfaceStyle = traitCollection.userInterfaceStyle modeDetect(userInterfaceStyle: userInterfaceStyle) } override func viewDidAppear(_ animated: Bool) { navigationController?.navigationBar.barStyle = .black navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white] } func modeDetect(userInterfaceStyle: UIUserInterfaceStyle) { switch userInterfaceStyle { case .light: navigationController?.navigationBar.barTintColor = .systemPink case .dark: navigationController?.navigationBar.barTintColor = .systemBackground default: break } }

以下 Objective-C 代碼使 iOS 13 導航欄的行為與我之前的版本相似:

    if (@available(iOS 13.0, *)) {
        // Setup iOS 13 navigation bar
        sharedSelector.navigationBar.scrollEdgeAppearance = sharedSelector.navigationBar.standardAppearance;
    } else {
        // Fallback on earlier versions
    }

使用適當的參數調用此函數。 此代碼工作正常。

open func showNavigationBar(large: Bool,
                            animated: Bool,
                            isTransparabar: Bool,
                            titleColor: UIColor,
                            barBackGroundColor: UIColor,
                            fontSize: CGFloat) {

        navigationController?.navigationBar.barTintColor = barBackGroundColor
        navigationController?.navigationBar.backgroundColor = barBackGroundColor
        navigationController?.navigationBar.isTranslucent = true
        self.navigationController?.setNavigationBarHidden(false, animated: animated)
        if large {
            self.navigationController?.navigationBar.prefersLargeTitles = true
            if #available(iOS 13.0, *) {
                let appearance = UINavigationBarAppearance()
                appearance.backgroundColor = barBackGroundColor
                appearance.titleTextAttributes = [.foregroundColor: titleColor]
                appearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor]

                navigationController?.navigationBar.standardAppearance = appearance
                navigationController?.navigationBar.compactAppearance = appearance
                navigationController?.navigationBar.scrollEdgeAppearance = appearance
            } else {
                self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor]
            }
        } else {
            self.navigationController?.navigationBar.prefersLargeTitles = false
            self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor!]
        }
    }

我只是在故事板中打開半透明

像這兒

@mohmmad alabid 的答案需要單獨應用於每個視圖控制器,如果您想要一個通用的 Objective-C 解決方案,請將其放在您的應用程序委托中的 didFinishLaunchingWithOptions 函數中。

if (@available(iOS 13.0, *)) {
    UINavigationBarAppearance* navBarAppearance = [[UINavigationBarAppearance alloc] init];
    [navBarAppearance configureWithOpaqueBackground];
    navBarAppearance.titleTextAttributes = @{NSForegroundColorAttributeName:NAVBAR_TEXT_COLOR};
    navBarAppearance.largeTitleTextAttributes = @{NSForegroundColorAttributeName: NAVBAR_TEXT_COLOR};
    navBarAppearance.backgroundColor = NAVBAR_COLOR;
    [[UINavigationBar appearance] setStandardAppearance: navBarAppearance];
    [[UINavigationBar appearance] setScrollEdgeAppearance: navBarAppearance];
}

邁克的解決方案很棒。

我提供了一種替代方法來更改適用於任何 iOS 版本的 UINavigationBar 顏色。

我們基本上將利用我們可以將 Image 設置為 UINavigationBar 的背景這一事實。

第一的

添加擴展以從任何 UColor 生成 UIImage 請注意,如果需要,您還可以稍后編寫擴展以從十六進制或其他格式生成 UIColor。

extension UIColor {
    func image(_ size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
        return UIGraphicsImageRenderer(size: size).image { rendererContext in
            self.setFill()
            rendererContext.fill(CGRect(origin: .zero, size: size))
        }
    }

}

感謝@neoneye提供了這個很棒的UIColor擴展 :)

第二

現在我們開始談正事:

private func setupNavigationBarAppearance(navBar: UINavigationBar) {
    navBar.isTranslucent = false
    let navBarColorImage = UIColor.blue.image()
    navBar.setBackgroundImage(navBarColorImage, for: .default)
    navBar.tintColor = UIColor.white
}

因為我們已經將不透明的彩色圖像設置為背景,所以我們不需要檢查 iOS 13

我希望這可以幫助一些人自定義他們的導航欄。

干杯!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM