SwiftUI中使用List和ForEach显示字符串数组模型数据异常问题
问题
我需要展示OrderInfo模型中的动态列表项,当前代码无编译错误,但存储字符串数组的pickupItems对应的List无法显示。模型的其他属性(pickupSection、pickupStand)可以正常访问,怀疑问题出在字符串数组的ForEach使用方式上。
模型代码
struct OrderInfo: Codable, Identifiable, Hashable { var id: Int var orderNumber: String var activeOrderStatus: Bool var pickupSection: Int var pickupStand: String var pickupItems: [String] }
视图代码
struct CompletedOrderPickUp: View { var completedOrder: OrderInfo var body: some View { ScrollView { VStack { HStack { Text("Section") Spacer() Text("\(completedOrder.pickupSection)") } .pickUpDetailsTitleModifier() HStack { Text("Stand Name") Spacer() Text(completedOrder.pickupStand) } .pickUpDetailsTitleModifier() HStack { Text("Order Items") Spacer() } .pickUpDetailsTitleModifier() List { ForEach(completedOrder.pickupItems, id: \.self) { items in Text("\(items)") Text(items) } } } } } }
解决方案
你的代码有两个核心问题导致pickupItems列表无法正常显示:
ForEach返回多个View:SwiftUI要求
ForEach的闭包必须返回单个View实例,但你在闭包里直接放了两个Text视图,这会导致布局异常,List无法正确渲染每一行。需要把多个View包裹在HStack、VStack或Group中。ScrollView嵌套List:
List本身自带滚动功能,将它嵌套在ScrollView里会触发布局冲突,导致List的内容无法正常展示。你可以选择两种修改方式:
方案一:移除外层ScrollView,用List承载所有内容
把所有内容整合到List的Section中,利用List的原生滚动特性:
struct CompletedOrderPickUp: View { var completedOrder: OrderInfo var body: some View { List { Section { HStack { Text("Section") Spacer() Text("\(completedOrder.pickupSection)") } .pickUpDetailsTitleModifier() HStack { Text("Stand Name") Spacer() Text(completedOrder.pickupStand) } .pickUpDetailsTitleModifier() } Section("Order Items") { ForEach(completedOrder.pickupItems, id: \.self) { item in // 把两个Text包裹在HStack中,作为单个行View HStack { Text("\(item)") Text(item) } } } } } }
方案二:将List替换为VStack,保留外层ScrollView
如果需要保留外层ScrollView,把List换成VStack+Divider来模拟列表效果:
struct CompletedOrderPickUp: View { var completedOrder: OrderInfo var body: some View { ScrollView { VStack(spacing: 16) { HStack { Text("Section") Spacer() Text("\(completedOrder.pickupSection)") } .pickUpDetailsTitleModifier() HStack { Text("Stand Name") Spacer() Text(completedOrder.pickupStand) } .pickUpDetailsTitleModifier() HStack { Text("Order Items") Spacer() } .pickUpDetailsTitleModifier() // 用VStack替代List,添加Divider分隔行 VStack(spacing: 0) { ForEach(completedOrder.pickupItems, id: \.self) { item in HStack { Text("\(item)") Text(item) } .padding(.vertical, 8) Divider() } } } .padding() } } }
内容的提问来源于stack exchange,提问作者Pedro Cerrano
相关产品推荐
相关产品推荐

