SwiftUI中如何移除List顶部和底部的8pt内边距?
解决SwiftUI List与safeAreaInset间的8pt间距问题
这个8pt间距是Plain风格List默认的滚动内容内边距,用于适配系统默认布局逻辑,你可以通过以下两种方式消除:
方式一:iOS 16+ 简洁方案
使用scrollContentInsets修饰符直接覆盖List的默认内边距:
struct ContentView: View { private let items = (0..<50).map { "Item \($0)" } var body: some View { List { ForEach(items, id: \.self) { item in Text(item) .listRowInsets(EdgeInsets()) .frame(height: 50) .frame(maxWidth: .infinity, alignment: .leading) .background(.blue) } } .listStyle(.plain) .scrollContentInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0)) // 关键代码 .environment(\.defaultMinListRowHeight, 0) .safeAreaInset(edge: .top) { Text("Header") .frame(height: 50) .frame(maxWidth: .infinity) .background(.pink) } .safeAreaInset(edge: .bottom) { Text("Footer") .frame(height: 50) .frame(maxWidth: .infinity) .background(.pink) } } }
方式二:兼容iOS 15及以下
如果需要适配更低版本系统,可以通过修改UITableView的全局外观消除内边距,注意在页面消失时恢复默认值,避免影响其他页面:
struct ContentView: View { private let items = (0..<50).map { "Item \($0)" } var body: some View { List { ForEach(items, id: \.self) { item in Text(item) .listRowInsets(EdgeInsets()) .frame(height: 50) .frame(maxWidth: .infinity, alignment: .leading) .background(.blue) } } .listStyle(.plain) .environment(\.defaultMinListRowHeight, 0) .onAppear { UITableView.appearance().contentInset = .zero } .onDisappear { // 恢复系统默认内边距 UITableView.appearance().contentInset = .init(top: 0, left: 0, bottom: 0, right: 0) } .safeAreaInset(edge: .top) { Text("Header") .frame(height: 50) .frame(maxWidth: .infinity) .background(.pink) } .safeAreaInset(edge: .bottom) { Text("Footer") .frame(height: 50) .frame(maxWidth: .infinity) .background(.pink) } } }
内容的提问来源于stack exchange,提问作者Mac
相关产品推荐
相关产品推荐

