You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 18:54:04