如何在支持macOS 11时将Bottom Bar置于NavigationView外部?
解决方案
在macOS 11的SwiftUI环境下,你可以通过将NavigationView与底部栏置于同一个父容器的方式,实现底部栏在NavigationView外部、不覆盖侧边栏且无需重复实例化的效果。
实现代码示例
import SwiftUI struct MainView: View { var body: some View { VStack(spacing: 0) { // 导航视图(包含侧边栏与主内容区) NavigationView { // 侧边栏列表 List { NavigationLink("视图1", destination: View1()) NavigationLink("视图2", destination: View2()) } .listStyle(SidebarListStyle()) // 默认主内容视图 Text("请选择一个视图") } .frame(maxHeight: .infinity) // 让导航视图占据剩余垂直空间 // 全局底部栏 HStack { Button("功能按钮1") {} Spacer() Button("功能按钮2") {} Spacer() Button("功能按钮3") {} } .padding(.horizontal) .frame(height: 50) .background(Color.gray.opacity(0.2)) } .frame(maxWidth: .infinity, maxHeight: .infinity) // 让父容器填满整个窗口 } } // 子视图示例 struct View1: View { var body: some View { Text("视图1的内容区域") .navigationTitle("视图1") } } struct View2: View { var body: some View { Text("视图2的内容区域") .navigationTitle("视图2") } }
原理说明
- 布局逻辑:通过
VStack垂直排布NavigationView和底部栏,NavigationView借助.frame(maxHeight: .infinity)占据除底部栏外的全部垂直空间,底部栏则固定在窗口底部。 - 侧边栏不被覆盖:
NavigationView的侧边栏属于其内部布局范畴,会被限制在NavigationView自身的空间内,不会被下方的底部栏遮挡。 - 避免重复创建:底部栏仅在主容器
MainView中初始化一次,所有通过NavigationLink跳转的子视图都会共用这个底部栏,无需在每个子视图中重复实现。
该方案完全兼容macOS 11,用到的SidebarListStyle、frame修饰符等API在macOS 11及以上版本均支持。
内容的提问来源于stack exchange,提问作者user14239891
相关产品推荐
相关产品推荐

