SwiftUI开发中List组件列表项增加时frame高度不自动变化问题求解
解决方法
问题根源
SwiftUI 的 List 本质基于 UIKit 的 UITableView 实现,默认自带滚动能力,会优先使用父视图分配的固定高度,不会自动根据内部元素数量适配高度。你当前代码嵌套了两层 List,内层 List 高度被默认限制,才会出现内容遮挡、需要滚动才能查看的问题。
最优方案(无需保留列表特性)
如果你不需要内层列表的滚动、侧滑删除等原生 List 特性,直接将内层 List 替换为 VStack 即可,VStack 会自动根据内部元素数量动态调整高度,完全符合你的需求。
修改后的核心代码如下:
struct PunishView: View { @StateObject var viewModal = StocksViewModel() @State var text = "" var body: some View { NavigationView { VStack { List { Section(header: Text("Lapsus")) { TextField("Naam...", text: $text) .frame(minWidth: 0, idealWidth: 100, maxWidth: .infinity, minHeight: 0, idealHeight: 30, maxHeight: .infinity, alignment: .center) Button(action: { self.tryToAddToList() }, label: { Text("Voeg toe") .bold() .frame( width: 400, height: 60, alignment: .center) .background(Color.purple) .cornerRadius(10) .foregroundColor(Color.white) }) .frame(minWidth: 0, idealWidth: 100, maxWidth: .infinity, minHeight: 0, idealHeight: 30, maxHeight: .infinity, alignment: .center) } // 把原来的内层List替换成VStack VStack { ForEach(viewModal.stocks) { stock in AdPistumLijst(title: stock.title) } } } .listStyle(PlainListStyle()) } .navigationTitle("Straffenlijst") } } func tryToAddToList (){ guard !text.trimmingCharacters(in: .whitespaces).isEmpty else { return } let newStock = Stock(title: text) viewModal.stocks.append(newStock) text = "" } }
备选方案(需保留List特性)
如果你需要保留 List 的原生特性(比如侧滑删除、系统列表样式),可以手动计算 List 高度,给内层 List 绑定动态高度:
假设你的自定义行 AdPistumLijst 高度为固定值44(系统默认列表行高),代码修改如下:
List { ForEach(viewModal.stocks) {stock in AdPistumLijst(title: stock.title) } } .listStyle(PlainListStyle()) // 绑定动态高度 .frame(height: 44 * CGFloat(viewModal.stocks.count))
如果你的行高是动态的,可以通过 PreferenceKey 捕获每行实际高度再计算总高度,适配性更强。
内容的提问来源于stack exchange,提问作者user13854357
相关产品推荐
相关产品推荐

