SwiftUI列表横向滚动行内容被裁剪的问题修复求助
解决SwiftUI List行高度适配横向ScrollView内最高子项的问题
在SwiftUI中实现了一个List,每行都是横向ScrollView,内部子项高度由文本行数决定,当前子项内容出现被裁剪的情况,需要让列表行自动适配该行内最高子项的高度。
原实现代码
struct ContentView: View { var body: some View { List { ForEach(1..<12) { index in ScrollView(.horizontal, showsIndicators: false) { LazyHStack(alignment: .top, spacing: 4) { ForEach(1..<10) { innerIndex in VStack(alignment: .leading, spacing: 0) { Rectangle() .frame(width: 100, height: 100) .foregroundColor(.blue) let text = Array(repeating: "A", count: innerIndex * index).joined(separator: " ") Text(text) .font(.system(size: 10)) .multilineTextAlignment(.leading) .lineLimit(2, reservesSpace: false) .fixedSize(horizontal: false, vertical: true) Text("Item no: \(innerIndex)") .font(.system(size: 16)) Spacer(minLength: 0) } .frame(width: 100) .background(Color.yellow.opacity(0.5)) } } } .listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0)) .listRowSeparator(.hidden) } } .listStyle(.plain) .environment(\.defaultMinListRowHeight, 0) } }
问题分析
ScrollView默认会优先压缩自身高度以适应父容器(List行),导致List行无法感知内部横向列表中最高子项的真实高度,最终造成子项内容被裁剪。
解决方案及修改代码
通过以下关键调整让List行自动适配最高子项高度:
- 移除子项VStack中的
Spacer(minLength: 0),避免强制拉伸子项高度 - 给
LazyHStack添加.fixedSize(horizontal: false, vertical: true),让横向栈根据内部最高子项确定自身高度 - 给
ScrollView添加.fixedSize(horizontal: false, vertical: true),确保ScrollView不会压缩高度,传递正确高度给List行 - 移除
.environment(\.defaultMinListRowHeight, 0),避免过度限制List行最小高度
修改后的完整代码:
struct ContentView: View { var body: some View { List { ForEach(1..<12) { index in ScrollView(.horizontal, showsIndicators: false) { LazyHStack(alignment: .top, spacing: 4) { ForEach(1..<10) { innerIndex in VStack(alignment: .leading, spacing: 0) { Rectangle() .frame(width: 100, height: 100) .foregroundColor(.blue) let text = Array(repeating: "A", count: innerIndex * index).joined(separator: " ") Text(text) .font(.system(size: 10)) .multilineTextAlignment(.leading) .lineLimit(2, reservesSpace: false) .fixedSize(horizontal: false, vertical: true) Text("Item no: \(innerIndex)") .font(.system(size: 16)) } .frame(width: 100) .background(Color.yellow.opacity(0.5)) } } .fixedSize(horizontal: false, vertical: true) } .fixedSize(horizontal: false, vertical: true) .listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0)) .listRowSeparator(.hidden) } } .listStyle(.plain) } }
修改后,每个List行都会自动匹配该行横向ScrollView内最高子项的高度,子项内容不再被裁剪。
内容的提问来源于stack exchange,提问作者Wujo
相关产品推荐
相关产品推荐

