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

UINavigationItem.LargeTitleDisplayMode.never在UISplitViewController下仍显示大标题背景异常

iOS15 UISplitViewController嵌套场景下导航栏外观异常问题

iOS 15默认导航栏滚动到顶部时为半透明效果,由于当前视图控制器展示UIMapView,我希望仅在该页面关闭该效果,其余页面保留iOS 15的默认新特性。

我已经将navigationItem.largeTitleDisplayMode设置为.never,相关代码如下:

override func viewDidLoad() {
    super.viewDidLoad()

    if #available(iOS 15.0, *) {
        let appearance = UINavigationBarAppearance()
        appearance.configureWithDefaultBackground()
        self.navigationItem.scrollEdgeAppearance = appearance
    }
}

但运行后导航栏仍然显示大标题模式下的背景,我尝试将navigationItem.largeTitleDisplayMode先设为.always再改回.never也无法修复该问题。

异常效果示意图

我仅在UINavigationController嵌套在UISplitViewController的场景下能复现该问题,结构如下图:
页面层级结构示意图

如果不使用UISplitViewController,仅用UINavigationController -> 带按钮的UIViewController -> 带UIMapView的UIViewController的层级时,UINavigationBar表现完全正常。

更奇怪的是,在iOS 14上运行该示例时,UINavigationBar外观正常,但iOS 15上被导航栏覆盖的地图区域无法响应交互。

请问是我哪里配置错误,还是这属于iOS系统本身的Bug?


解决方案

这是iOS 15的已知系统Bug,UISplitViewController嵌套UINavigationController的场景下,单个ViewController的navigationItem属性不会被系统正确读取,会优先使用UINavigationBar的全局配置。你可以按以下步骤修复:

  • 把导航栏配置逻辑从viewDidLoad移到viewWillAppear,确保页面展示时配置能被系统实时读取,同时设置standardAppearance和scrollEdgeAppearance,并同步给当前导航栏:
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // 强制关闭当前页面大标题
    navigationItem.largeTitleDisplayMode = .never
    navigationController?.navigationBar.prefersLargeTitles = false
    
    if #available(iOS 15.0, *) {
        let appearance = UINavigationBarAppearance()
        // 需完全不透明就用configureWithOpaqueBackground,保留默认半透用configureWithDefaultBackground
        appearance.configureWithDefaultBackground()
        // 单个item的两个外观都要设置,避免场景切换时读取缺省值
        navigationItem.standardAppearance = appearance
        navigationItem.scrollEdgeAppearance = appearance
        // 同步给导航栏设置,兼容UISplitViewController的特殊逻辑
        navigationController?.navigationBar.standardAppearance = appearance
        navigationController?.navigationBar.scrollEdgeAppearance = appearance
    }
}
  • 修复地图交互被遮挡问题:调整MapView的顶部约束对齐安全区顶部,同时关闭布局延伸到不透明栏下方的配置:
override func viewDidLoad() {
    super.viewDidLoad()
    extendedLayoutIncludesOpaqueBars = false
    // 若为代码布局MapView,添加以下约束
    mapView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        mapView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
        mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
    ])
}
  • 在页面消失时还原导航栏配置,保证其他页面可以正常使用iOS 15默认特性:
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if #available(iOS 15.0, *) {
        navigationController?.navigationBar.standardAppearance = UINavigationBarAppearance()
        navigationController?.navigationBar.scrollEdgeAppearance = nil
    }
    navigationController?.navigationBar.prefersLargeTitles = true
}

内容的提问来源于stack exchange,提问作者Zandor Smith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 18:18:01