Swift:滚动视图时Navigation Bar变色,如何编程设置导航栏和状态栏背景色
滚动时导航栏和状态栏颜色变化,是因为iOS 13+ 引入了UINavigationBarAppearance导航栏外观配置,默认区分了「滚动到顶部边缘」和「正常滚动」两种状态的样式,你直接设置navigationBar.backgroundColor不会覆盖所有状态的配置,同时默认导航栏开启半透明效果,会受下层TableView滚动的内容影响颜色。
以下是可直接使用的修复代码:
import UIKit class TestViewController: UIViewController, UIGestureRecognizerDelegate { @IBOutlet weak var tableView: UITableView! let faqList : [FAQ] = [ FAQ(title: "Test 1", content: "Answer 1"), FAQ(title: "Test 2", content: "Answer 2"), FAQ(title: "Test 3", content: "Answer 3"), FAQ(title: "Test 4", content: "Answer 4"), FAQ(title: "Test 5", content: "Answer 5"), FAQ(title: "Test 6", content: "Answer 6"), FAQ(title: "Test 7", content: "Answer 7"), FAQ(title: "Test 8", content: "Answer 8"), FAQ(title: "Test 9", content: "Answer 9"), FAQ(title: "Test 10", content: "Answer 10"), FAQ(title: "Test 11", content: "Answer 11"), FAQ(title: "Test 12", content: "Answer 12"), FAQ(title: "Test 13", content: "Answer 13"), FAQ(title: "Test 14", content: "Answer 14"), ] override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self tableView.backgroundColor = UIColor(named: "BackgroundColor") tableView.register(UINib(nibName: "ButtonTableViewCell", bundle: nil), forCellReuseIdentifier: "ButtonCell") // 替换原有的导航栏颜色设置代码 setCustomNavigationBar() // 如需状态栏和导航栏同色则调用下面这行,不需要可删除 setStatusBarBackgroundColor(color: .blue) } // 配置固定样式的导航栏 private func setCustomNavigationBar() { guard let navBar = navigationController?.navigationBar else { return } // 关闭半透明,避免颜色受下层内容影响,需要半透明效果可删除这行 navBar.isTranslucent = false if #available(iOS 13.0, *) { let appearance = UINavigationBarAppearance() // 设置导航栏背景色 appearance.backgroundColor = .blue // 去掉导航栏底部默认的阴影分割线,不需要可删除 appearance.shadowColor = .clear // 统一所有场景下的导航栏外观 navBar.standardAppearance = appearance navBar.scrollEdgeAppearance = appearance navBar.compactAppearance = appearance } else { // iOS13以下版本的兼容写法 navBar.barTintColor = .blue navBar.shadowImage = UIImage() navBar.setBackgroundImage(UIImage(), for: .default) } } // 设置状态栏背景色 private func setStatusBarBackgroundColor(color: UIColor) { if #available(iOS 13.0, *) { guard let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }), let statusBarFrame = window.windowScene?.statusBarManager?.statusBarFrame else { return } let statusBarView = UIView(frame: statusBarFrame) statusBarView.backgroundColor = color window.addSubview(statusBarView) } else { guard let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView else { return } statusBar.backgroundColor = color } } } extension TestViewController: UITableViewDelegate { } extension TestViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return faqList.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ButtonCell", for: indexPath) as! ButtonTableViewCell let buttonCell = faqList[indexPath.row] cell.titleLabel.text = buttonCell.title cell.trailingIconBackground.isHidden = true cell.buttonView.backgroundColor = .brown cell.buttonView.layer.cornerRadius = 10 cell.buttonView.layer.masksToBounds = true cell.selectionStyle = UITableViewCell.SelectionStyle.none return cell } }
如果需要全局所有页面的导航栏都使用该样式,可以把setCustomNavigationBar里的逻辑放到AppDelegate的didFinishLaunchingWithOptions方法中执行,无需每个页面单独配置。
内容的提问来源于stack exchange,提问作者Punreach Rany
相关产品推荐
相关产品推荐

