SwiftUI List行高未匹配裁剪VStack的Frame高度(已设defaultMinListRowHeight为0)
SwiftUI List行高不跟随裁剪后视图高度的问题解决
问题原因
SwiftUI的List行高是基于子视图的**固有内容尺寸(Intrinsic Content Size)**计算的。你给VStack设置.frame(height: x)再加上.clipped(),只是在视觉上裁剪了超出frame的部分,但VStack本身的固有尺寸还是所有内部Text叠加后的总高度。List会优先参考这个固有尺寸分配行高,所以即使设置了defaultMinListRowHeight = 0,也无法让行高匹配裁剪后的frame高度。
解决方案
方案1:直接指定listRowHeight
既然已经明确每个行的目标高度,直接给每个List行添加.listRowHeight()修饰符,和VStack的frame高度保持一致即可:
struct SwiftUIView: View { var body: some View { List { VStack{ Text("TEST") Text("TEST") Text("TEST") Text("TEST") Text("TEST") } .background(.gray) .frame(height: 5) .clipped() .listRowBackground(Color.yellow) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) .listRowHeight(5) // 绑定行高 VStack{ Text("TEST") Text("TEST") Text("TEST") Text("TEST") } .background(.purple) .frame(height: 10) .clipped() .listRowBackground(Color.red) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) .listRowHeight(10) // 绑定行高 VStack{ Text("TEST") Text("TEST") Text("TEST") } .background(.green) .frame(height: 15) .clipped() .listRowBackground(Color.blue) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) .listRowHeight(15) // 绑定行高 } .environment(\.defaultMinListRowHeight, 0) .listStyle(PlainListStyle()) } }
方案2:修改视图的固有尺寸
如果不想手动指定listRowHeight,可以通过对齐指南覆盖List对行高的计算逻辑,让它直接使用我们设置的frame高度:
struct SwiftUIView: View { var body: some View { List { VStack{ Text("TEST") Text("TEST") Text("TEST") Text("TEST") Text("TEST") } .background(.gray) .frame(height: 5) .clipped() .alignmentGuide(.listRowHeight) { $0[.bottom] - $0[.top] } .listRowBackground(Color.yellow) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) VStack{ Text("TEST") Text("TEST") Text("TEST") Text("TEST") } .background(.purple) .frame(height: 10) .clipped() .alignmentGuide(.listRowHeight) { $0[.bottom] - $0[.top] } .listRowBackground(Color.red) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) VStack{ Text("TEST") Text("TEST") Text("TEST") } .background(.green) .frame(height: 15) .clipped() .alignmentGuide(.listRowHeight) { $0[.bottom] - $0[.top] } .listRowBackground(Color.blue) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) } .environment(\.defaultMinListRowHeight, 0) .listStyle(PlainListStyle()) } }
说明
方案1更直接,适合已知固定行高的场景;方案2更灵活,适合动态计算高度的场景,让List自动跟随frame高度调整行高。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

