appDelegate 中的委托函数不会更改导航栏颜色
Delegate function in appDelegate doesn't change navbar colors
Xcode11.3.1,iOS13
如果应用程序中存在特定条件,我将尝试更改所有视图控制器上导航栏的颜色。使用 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!
我建议,因为您想根据 Flag 模型值动态更改 NavigationBar 主题(如背景颜色),不要采用 AppDelegate 方式,因为它会为您做一次,而且它更多地被认为是在实际创建任何视图之前设置 NavigationBar 样式的全局方式。
有几种方法可以应用它,例如通过 extension ViewController
、inheritance with base class
.. 以及您可以 get/set 标志值更改导航颜色的不同方法,例如通过 userdefaults
、variables
...我将展示一个示例来帮助您继续:
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 的标志设置为加拿大),并且在情节提要中具有 ViewController 和 UINavigationController 的根 viewcontroller,如下所示:
会让应用看起来像:
重构改进
你还可以做一些事情,只是为了更容易管理代码、标志和颜色,将它们组织在一个结构中,我选择了一个枚举作为例子,但你也可以用其他方式来做,只是为了给你一个例子,你可以这样做:
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
}
}
Xcode11.3.1,iOS13
如果应用程序中存在特定条件,我将尝试更改所有视图控制器上导航栏的颜色。使用 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!
我建议,因为您想根据 Flag 模型值动态更改 NavigationBar 主题(如背景颜色),不要采用 AppDelegate 方式,因为它会为您做一次,而且它更多地被认为是在实际创建任何视图之前设置 NavigationBar 样式的全局方式。
有几种方法可以应用它,例如通过 extension ViewController
、inheritance with base class
.. 以及您可以 get/set 标志值更改导航颜色的不同方法,例如通过 userdefaults
、variables
...我将展示一个示例来帮助您继续:
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 的标志设置为加拿大),并且在情节提要中具有 ViewController 和 UINavigationController 的根 viewcontroller,如下所示:
会让应用看起来像:
重构改进
你还可以做一些事情,只是为了更容易管理代码、标志和颜色,将它们组织在一个结构中,我选择了一个枚举作为例子,但你也可以用其他方式来做,只是为了给你一个例子,你可以这样做:
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
}
}