Xcode 11.3.1,iOS 13
如果应用中存在某种特定条件,我将尝试在所有View Controller上更改navigationBar的颜色。使用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调用它,就像这样,即使该函数正在接收适当的数据,它也不会对navBars起作用在其参数中:
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
等多种方式进行应用。另外,也可以通过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的标志设置为Canada),并在Storyboard中将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
}
}