SwiftUI NavigationView中如何为自定义导航栏预留空间
问题描述
隐藏系统导航栏并使用自定义导航栏后,List被导航栏遮挡。希望滚动时List显示在导航栏下方,且不能为List添加padding,这属于安全区域适配问题。
期望效果

实际效果

现有代码
import SwiftUI struct ContentView: View { var body: some View { NavigationView { TabView { FirstView() .tabItem { Image(systemName: "folder.fill") Text("Home") } SecondView() .tabItem { Image(systemName: "folder.fill") Text("SecondView") } } .navigationBarTitleDisplayMode(.inline) } } } struct FirstView: View { var body: some View { ZStack(alignment: .top) { List { ForEach(0..<40, id: \.self) { index in Text("cell view \(index)") } } .listStyle(.inset) HStack { Text("首页") } .frame(maxWidth: .infinity) .frame(height: 44) .background(.bar) } .navigationBarTitleDisplayMode(.inline) //.ignoresSafeArea(edges: .) } } struct SecondView: View { var body: some View { List { ForEach(0..<40, id: \.self) { index in Text("FirstView2") } } .listStyle(.inset) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
解决方案
核心是调整安全区域适配逻辑,让List和自定义导航栏的布局层级清晰:
- 彻底隐藏系统导航栏:在
FirstView中添加.navigationBarHidden(true),避免系统导航栏的布局影响自定义导航栏。 - 让List忽略顶部安全区域:给List添加
.ignoresSafeArea(edges: .top),让List内容从屏幕顶部开始布局,滚动时自然处于自定义导航栏下方,无需额外padding。 - 可选:适配刘海屏安全区域:给自定义导航栏添加顶部padding,适配不同设备的刘海高度,避免导航栏内容被遮挡。
修改后的FirstView代码:
struct FirstView: View { var body: some View { ZStack(alignment: .top) { List { ForEach(0..<40, id: \.self) { index in Text("cell view \(index)") } } .listStyle(.inset) .ignoresSafeArea(edges: .top) // 让List忽略顶部安全区域 HStack { Text("首页") } .frame(maxWidth: .infinity) .frame(height: 44) .background(.bar) .padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0) // 适配刘海屏顶部高度 } .navigationBarTitleDisplayMode(.inline) .navigationBarHidden(true) // 隐藏系统导航栏 } }
内容的提问来源于stack exchange,提问作者gaohomway
相关产品推荐
相关产品推荐

