簡體   English   中英

appDelegate 中的委托函數不會改變導航欄顏色

[英]Delegate function in appDelegate doesn't change navbar colors

Xcode 11.3.1,iOS 13

如果應用程序中存在特定條件,我正在嘗試更改所有視圖控制器上導航欄的顏色。 使用 AppDelegate 中的委托函數,使用最初設置全局顏色的相同代碼似乎是合乎邏輯的。

這是我的代碼:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    var myColor : UIColor?

    let themeColorUS = UIColor(red: 0.991, green: 0.621, blue: 0.022, alpha: 1.00)
    let themeColorCanada = UIColor(red: 0.001, green: 0.686, blue: 0.000, alpha: 1.00)
    let themeColorGeneral = UIColor(red: 0.000, green: 0.954, blue: 0.969, alpha: 1.00)

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        UserDefaults.standard.setValue(false, forKey: "_UIConstraintBasedLayoutLogUnsatisfiable")

        setBarColors(issuingFlag: "General")

        return true
    }

...

func setBarColors(issuingFlag:String) {

    if issuingFlag == "US" {
        myColor = themeColorUS
    }else if issuingFlag == "Canada"{
        myColor = themeColorCanada
    }else{
        myColor = .magenta
    }

    print("issuingFlag == \(issuingFlag)")

    if #available(iOS 13.0, *) {

        let appearance = UINavigationBarAppearance()
        appearance.backgroundColor = myColor
        appearance.titleTextAttributes = [.foregroundColor: UIColor.black]
        appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.black]

        UINavigationBar.appearance().tintColor = .black
        UINavigationBar.appearance().standardAppearance = appearance
        UINavigationBar.appearance().compactAppearance = appearance
        UINavigationBar.appearance().scrollEdgeAppearance = appearance
    } else {
        UINavigationBar.appearance().tintColor = .black
        UINavigationBar.appearance().barTintColor = myColor
        UINavigationBar.appearance().isTranslucent = false
    }

}

除了在應用程序打開時對setBarColors()的初始調用(工作正常)之外,我還像這樣從應用程序內的 viewController 調用它,這對導航欄沒有任何作用,即使該函數在其范圍:

    if detailFlag.issuedBy == "Canada"{
    appDelegate.setBarColors(issuingFlag: "Canada")

    }else if detailFlag.issuedBy == "US"{
    appDelegate.setBarColors(issuingFlag: "US")
    }

有人可以幫助我了解為什么該功能不切換navBar顏色嗎?

蒂亞!

我建議,因為您想根據 Flag 模型值動態更改 NavigationBar 主題(如背景顏色),所以不要采用 AppDelegate 方式,因為這將為您完成一次,並且更多地被認為是在實際創建任何視圖之前設置 NavigationBar 樣式的全局方式。

有幾種方法可以應用它,比如通過extension ViewControllerinheritance with base class ......以及你可以獲取/設置標志值以更改導航顏色的不同方式,比如通過userdefaultsvariables ......我'將展示一個例子只是為了讓你開始:

import UIKit

class ViewController: BaseViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        currentFlag = "Canada"
    }
}

class BaseViewController: UIViewController {

    var currentFlag: String = "General" {
        didSet {
            setNavBarColor()
        }
    }

    private let themeColorUS = UIColor(red: 0.991, green: 0.621, blue: 0.022, alpha: 1.00)
    private let themeColorCanada = UIColor(red: 0.001, green: 0.686, blue: 0.000, alpha: 1.00)
    private let themeColorGeneral = UIColor(red: 0.000, green: 0.954, blue: 0.969, alpha: 1.00)

    override func viewDidLoad() {
        super.viewDidLoad()

        setNavBarColor()
    }

    private func setNavBarColor() {
        navigationController?.navigationBar.barTintColor = getBarColor(for: currentFlag)
    }

    private func getBarColor(for flag: String) -> UIColor {
        if flag == "US" {
            return themeColorUS
        } else if flag == "Canada" {
            return themeColorCanada
        }

        return themeColorGeneral
    }
}

這意味着,我們從AppDelegate刪除了設置其樣式的全局方式,因此我的didFinishLaunchingWithOptions看起來像:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    return true
}

運行以下代碼(將我的 ViewController 的標志設置為 Canada),並在情節提要中使用 ViewController 和 UINavigationController 的根視圖控制器,如下所示:

將使應用程序看起來像:


重構以改進

此外,您還可以做一些事情,只是為了更輕松地管理代碼、標志和顏色,將它們組織在一個結構中,我選擇了一個枚舉作為示例,但您也可以通過其他方式做到這一點,只是為了給您您可以通過這種方式完成的示例:

import UIKit

enum Flag {
    case us
    case canada
    case general

    static let `default` = Flag.general

    init(rawValue: String) {
        switch rawValue {
        case "US":
            self = .us
        case "Canada":
            self = .canada
        case "General":
            self = .general
        default:
            self = .default
        }
    }

    var themeColor: UIColor {
        switch self {
        case .us:
            return UIColor(red: 0.001, green: 0.686, blue: 0.000, alpha: 1.00)
        case .canada:
            return UIColor(red: 0.001, green: 0.686, blue: 0.000, alpha: 1.00)
        case .general:
            return UIColor(red: 0.000, green: 0.954, blue: 0.969, alpha: 1.00)
        }
    }
}

class ViewController: BaseViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        currentFlag = .canada
    }
}

class BaseViewController: UIViewController {

    var currentFlag: Flag = .default {
        didSet {
            setNavBarColor()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        setNavBarColor()
    }

    private func setNavBarColor() {
        navigationController?.navigationBar.barTintColor = currentFlag.themeColor
    }
}

暫無
暫無

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

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