【问题标题】:Delegate function in appDelegate doesn't change navbar colorsappDelegate 中的委托功能不会更改导航栏颜色
【发布时间】:2020-03-16 06:16:31
【问题描述】:

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 颜色吗?

TIA!

【问题讨论】:

    标签: ios swift uinavigationbar appdelegate


    【解决方案1】:

    我建议,因为您想根据 Flag 模型值动态更改 NavigationBar 主题(如背景颜色),所以不要采用 AppDelegate 方式,因为这将为您完成一次,并且被认为更多的是在实际创建任何视图之前设置 NavigationBar 样式的全局方法。

    您可以通过几种方式应用它,例如通过extension ViewControllerinheritance with base class.. 以及您可以获取/设置标志值以更改导航颜色的不同方式,例如通过userdefaults、@ 987654326@... 我会举一个例子来帮助你:

    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),并在 Storyboard 中使用 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
        }
    }
    

    【讨论】:

    • 非常感谢您的周到和详细的回答!由于所有冠状病毒的疯狂,我还没有实施它。很快就会这样做,并让您知道结果如何。再次感谢!
    • 不客气,如果这对您有用,请不要忘记将其标记为正确,否则请告诉我,我自己构建它是为了让您一步一步轻松地完成 kt。保持安全!
    • 昨晚刚开始整理,但一旦你明白我需要对我的 VC 进行子类化,我就看到了一些好事发生。那时已经是凌晨 3:00。这是我第一次使用枚举,所以很高兴你向我展示了它。我今天会做更多的工作。感谢您的检查!
    • @rattletrap99 确定!只要确保将其标记为正确,如果这对您也有效,以便其他人在将来检查答案时受益
    • 我在这里碰壁了。如果你有时间,你能回答几个问题吗?
    猜你喜欢
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 2017-02-17
    • 2011-10-14
    相关资源
    最近更新 更多