使用新的 UINavigationBarAppearance() API 在单个 ViewController 上设置 navigationBar 颜色?

Use new UINavigationBarAppearance() API to set navigationBar color on a single ViewController?

提问人:stompy 提问时间:9/22/2022 最后编辑:Swift Dev Journalstompy 更新时间:9/23/2022 访问量:168

问:

我需要为单个 .我目前正在做的是设置 nav 颜色并将其重置为 .clear(因此它使用在新推送的 VC 上设置的任何颜色)。虽然这种排序有效,但它的速度还不够快,因为在推送动画结束之前不会应用 .clear 颜色,导致 navigationBar 颜色在最终重置为 .clear 之前有半秒钟是可见的。ViewControllerviewDidLoad()viewWillDissappear

当前代码如下所示:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.navigationBar.setNavBarColor(color: .red)
}

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        navigationController?.navigationBar.setNavBarColor(color: .clear)
}


func setNavBarColor(color: UIColor) {
    let appearance: UINavigationBarAppearance = UINavigationBarAppearance()
    appearance.configureWithTransparentBackground()
    appearance.backgroundColor = color
    self.standardAppearance = appearance
    self.scrollEdgeAppearance = appearance
}

这有效,但速度不够快,因为更改仅在推送动画结束后生效。有什么提示吗?

iOS Swift Cocoa-Touch UIKit的

评论


答:

0赞 Fabio 9/22/2022 #1

使用我的扩展设置导航栏:

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
  }
 }
}

在 viewWillAppear 或 viewDidLoad 中调用它并更改背景颜色,在您的情况下将背景设置为清除...如何使用:

configureNavigationBar(largeTitleColor: .black, backgoundColor: .white, tintColor: .black, title: "yourTitle", preferredLargeTitle: true)

在本例中,在启动控制器的 viewWillAppear 中调用 configureNavigationBar func,在目标控制器的 viewDidLoad 中调用 configureNavigationBar。欧美: 在 SceneDelegate 中,在 scene function 下设置启动控制器:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    window = UIWindow(windowScene: windowScene)
    window?.makeKeyAndVisible()
    let controller = UINavigationController(rootViewController: StartController())
    window?.rootViewController = controller
    if #available(iOS 13, *) {
        window?.overrideUserInterfaceStyle = .dark
    }
}

这是 StartController:

import UIKit

class StartController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .white
    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "GO", style: .plain, target: self, action: #selector(handleGo))
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    configureNavigationBar(largeTitleColor: .white, backgoundColor: .black, tintColor: .white, title: "Start", preferredLargeTitle: true)
}

@objc fileprivate func handleGo() {
    let controller = DestinationController()
    navigationController?.pushViewController(controller, animated: true)
 }
}

这是 DestinationController:

import UIKit

class DestinationController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .white
    configureNavigationBar(largeTitleColor: .white, backgoundColor: .red, tintColor: .white, title: "Destination", preferredLargeTitle: true)
 }
}

结果:

enter image description here

评论

0赞 stompy 9/23/2022
在目标 VC 上将 .clear 设置为 navBar 颜色时似乎不起作用。尝试执行 view.backgroundColor = .purple 以强制目标 VC 完全为紫色,然后在 viewDidLoad 或 viewWillAppear 上设置清晰的 navBar 颜色并检查结果。从一个 VC 推送到另一个 VC 时,我在更改 navBar 颜色时遇到了相同的延迟。