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

Swift中如何在状态栏与导航栏之间添加UIView?现有方案无效

解决Swift中状态栏与导航栏之间添加UIView的问题

嘿,我看你在Swift里想给状态栏和导航栏之间加个自定义UIView踩坑了,咱们来一步步捋清楚问题出在哪,再给你靠谱的解决方案!

你当前代码的问题

你之前的代码是先把newView加到了keyWindow,然后才设置导航控制器为根视图控制器——这就导致导航控制器的视图层级会覆盖你的newView,直接把它挡住了。而且从iOS13开始,直接操作keyWindow也不是最佳实践,多窗口场景下很容易出问题。

下面给你两种实用的解决方案,按需选择:

方法一:直接调整导航栏位置,插入自定义视图

这个方法适合快速实现需求,直接在设置根控制器之后,给导航控制器的视图添加自定义View,再把导航栏往下挪:

// 先初始化根控制器和导航控制器
let rootVC: HomeVC = UIStoryboard(name: "Home", bundle: nil).instantiateViewController()
navController = UINavigationController(rootViewController: rootVC)
self.window?.rootViewController = self.navController
self.window?.makeKeyAndVisible()

// 创建自定义视图和内部的Label
let customHeaderView = UIView()
customHeaderView.backgroundColor = .orange // 设个颜色方便看效果
customHeaderView.translatesAutoresizingMaskIntoConstraints = false

let label = UILabel()
label.text = "header"
label.textColor = .black
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
customHeaderView.addSubview(label)

// 把自定义视图加到导航控制器的view里
navController.view.addSubview(customHeaderView)

// 设置约束:顶部对齐状态栏底部,左右撑满屏幕,高度自定义
let statusBarHeight = navController.view.safeAreaInsets.top // 适配所有机型的状态栏高度
NSLayoutConstraint.activate([
    customHeaderView.topAnchor.constraint(equalTo: navController.view.topAnchor, constant: statusBarHeight),
    customHeaderView.leadingAnchor.constraint(equalTo: navController.view.leadingAnchor),
    customHeaderView.trailingAnchor.constraint(equalTo: navController.view.trailingAnchor),
    customHeaderView.heightAnchor.constraint(equalToConstant: 30), // 这里可以改你想要的高度
    
    // Label居中
    label.centerXAnchor.constraint(equalTo: customHeaderView.centerXAnchor),
    label.centerYAnchor.constraint(equalTo: customHeaderView.centerYAnchor)
])

// 调整导航栏的位置,让它贴在自定义视图的下方
navController.navigationBar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    navController.navigationBar.topAnchor.constraint(equalTo: customHeaderView.bottomAnchor),
    navController.navigationBar.leadingAnchor.constraint(equalTo: navController.view.leadingAnchor),
    navController.navigationBar.trailingAnchor.constraint(equalTo: navController.view.trailingAnchor)
])

方法二:自定义导航控制器(推荐复用)

如果你的多个页面都需要这个效果,最好把逻辑封装到自定义导航控制器里,这样不用重复写代码:

class CustomNavigationController: UINavigationController {
    
    private let customHeaderView = UIView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupCustomHeader()
    }
    
    private func setupCustomHeader() {
        // 配置自定义视图
        customHeaderView.backgroundColor = .orange
        customHeaderView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(customHeaderView)
        
        let label = UILabel()
        label.text = "header"
        label.textColor = .black
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
        customHeaderView.addSubview(label)
        
        // 设置约束
        let statusBarHeight = view.safeAreaInsets.top
        NSLayoutConstraint.activate([
            customHeaderView.topAnchor.constraint(equalTo: view.topAnchor, constant: statusBarHeight),
            customHeaderView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            customHeaderView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            customHeaderView.heightAnchor.constraint(equalToConstant: 30),
            
            label.centerXAnchor.constraint(equalTo: customHeaderView.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: customHeaderView.centerYAnchor)
        ])
        
        // 调整导航栏位置
        navigationBar.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            navigationBar.topAnchor.constraint(equalTo: customHeaderView.bottomAnchor),
            navigationBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            navigationBar.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ])
    }
}

使用的时候只需要把普通的UINavigationController换成自定义的就行:

let rootVC: HomeVC = UIStoryboard(name: "Home", bundle: nil).instantiateViewController()
navController = CustomNavigationController(rootViewController: rootVC)
self.window?.rootViewController = self.navController
self.window?.makeKeyAndVisible()

几个注意事项

  • 一定要设置translatesAutoresizingMaskIntoConstraints = false,不然Auto Layout会和自动生成的约束冲突,导致布局异常。
  • 用view.safeAreaInsets.top获取状态栏高度比UIApplication.shared.statusBarFrame.height更靠谱,适配iOS13+的多窗口和不同机型。
  • 尽量避免直接往keyWindow加视图,优先添加到导航控制器或者当前页面的视图层级里,减少显示异常的概率。

内容的提问来源于stack exchange,提问作者Parth Dhorda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:25:13