SwiftUI中仅单个列表行忽略SafeArea的实现方案
SwiftUI实现List单行列忽略安全区的布局方案
问题描述
现有如下SwiftUI代码:
struct Example: View { var body: some View { List{ Color.red .listRowInsets(EdgeInsets()) Color.blue .listRowInsets(EdgeInsets()) } .listStyle(.grouped) List{ Color.green .listRowInsets(EdgeInsets()) Color.yellow .listRowInsets(EdgeInsets()) } .listStyle(.grouped) .ignoresSafeArea() } }
当前布局中,第二个List的绿、黄行因ignoresSafeArea()忽略了安全区,第一个List的红、蓝行均遵循安全区。需求是让第一个List中的蓝色行与第二个List的行同宽(忽略安全区),同时保持红色行的现有宽度(遵循安全区),但直接给蓝色行添加.ignoresSafeArea()无效果。
原因分析
List作为容器组件,默认会遵守安全区约束,其内部列表行的布局范围被限制在List的安全区边界内,单独给行添加.ignoresSafeArea()无法突破容器的布局限制,因此不会生效。
解决方案
可以通过listRowBackground给目标行设置忽略安全区的背景,同时将行内容设为EmptyView,以此让行背景突破安全区限制,实现和第二个List行相同的宽度。
修改后的代码如下:
struct Example: View { var body: some View { List { // 红色行保持原有布局,遵循安全区 Color.red .listRowInsets(EdgeInsets()) // 蓝色行通过listRowBackground实现忽略安全区 EmptyView() .listRowInsets(EdgeInsets()) .listRowBackground(Color.blue.edgesIgnoringSafeArea(.horizontal)) } .listStyle(.grouped) List { Color.green .listRowInsets(EdgeInsets()) Color.yellow .listRowInsets(EdgeInsets()) } .listStyle(.grouped) .ignoresSafeArea() } }
另一种实现思路
也可以使用GeometryReader获取屏幕宽度,直接给蓝色行设置匹配屏幕宽度的frame,结合edgesIgnoringSafeArea实现效果:
struct Example: View { var body: some View { GeometryReader { geo in VStack { List { Color.red .listRowInsets(EdgeInsets()) Color.blue .listRowInsets(EdgeInsets()) .frame(width: geo.size.width) .edgesIgnoringSafeArea(.horizontal) } .listStyle(.grouped) List { Color.green .listRowInsets(EdgeInsets()) Color.yellow .listRowInsets(EdgeInsets()) } .listStyle(.grouped) .ignoresSafeArea() } } } }
内容的提问来源于stack exchange,提问作者hanno
相关产品推荐
相关产品推荐

