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

SwiftUI隐藏导航栏工具栏时如何避免背景视图上移?

解决SwiftUI侧边菜单显示时背景视图上移的问题

点击侧边菜单时,导航栏工具栏被隐藏,但背景视图会自动向上移动,添加.navigationBarTitleDisplayMode(.inline)并未解决该问题。相关代码如下:

var body: some View {
    NavigationStack {
        ZStack {
            VStack {
                SlideView()
                ButtonView()
            }
            SideMenuView(isShowing: $showMenu, selectedTab: $selectedTab)
        }
        .toolbar(showMenu ? .hidden : .visible, for: .navigationBar)
        .navigationTitle("HKSTBC")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .topBarLeading) {
                Button(action: {
                    showMenu.toggle()
                }, label: {
                    Image(systemName: "line.3.horizontal")
                })
            }
        }
    }
}

解决思路及修改方案

问题根源是隐藏整个导航栏时,SwiftUI会自动调整内容布局以填充导航栏原本占据的空间,导致视图上移。我们可以通过保留导航栏占位高度,仅隐藏其内容和背景的方式避免布局偏移:

  1. 移除原有的.toolbar(showMenu ? .hidden : .visible, for: .navigationBar),始终保持导航栏可见
  2. 动态控制导航栏标题、工具栏按钮的显示状态
  3. 动态切换导航栏背景的显示/隐藏

修改后的代码如下:

var body: some View {
    NavigationStack {
        ZStack {
            VStack {
                SlideView()
                ButtonView()
            }
            SideMenuView(isShowing: $showMenu, selectedTab: $selectedTab)
        }
        .toolbar {
            ToolbarItem(placement: .topBarLeading) {
                // 仅在菜单未显示时展示侧边栏按钮
                if !showMenu {
                    Button(action: {
                        showMenu.toggle()
                    }, label: {
                        Image(systemName: "line.3.horizontal")
                    })
                }
            }
        }
        // 菜单显示时清空标题,否则显示原标题
        .navigationTitle(showMenu ? "" : "HKSTBC")
        .navigationBarTitleDisplayMode(.inline)
        // 菜单显示时隐藏导航栏背景,否则显示
        .toolbarBackground(showMenu ? .hidden : .visible, for: .navigationBar)
    }
}

另一种备选方案

如果需要完全隐藏导航栏但保持内容位置不变,可以给背景视图添加固定的顶部内边距,抵消导航栏的高度(inline模式下导航栏高度约为44pt):

var body: some View {
    NavigationStack {
        ZStack {
            VStack {
                SlideView()
                ButtonView()
            }
            // 添加与导航栏高度匹配的顶部内边距
            .padding(.top, 44)
            .edgesIgnoringSafeArea(.top)
            SideMenuView(isShowing: $showMenu, selectedTab: $selectedTab)
        }
        .toolbar(showMenu ? .hidden : .visible, for: .navigationBar)
        .navigationTitle("HKSTBC")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .topBarLeading) {
                Button(action: {
                    showMenu.toggle()
                }, label: {
                    Image(systemName: "line.3.horizontal")
                })
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:41:15