SwiftUI嵌套List无法滚动及.onDelete触发失败问题求助
问题解决:SwiftUI列表无法滚动、滑动删除失效
问题分析
你的代码存在两个核心问题导致列表交互失效:
ListInsideScontrino的视图层级错误,末尾直接添加的Color视图会干扰List的触摸事件传递- 承载视图
ScontrinoView中,List未获得足够布局空间,加上自定义mask的影响,导致滚动和滑动删除的触摸区域被限制
解决方案
1. 修复ListInsideScontrino的视图结构
将背景色放到ZStack底层,避免额外视图覆盖List的交互区域:
import SwiftUI struct ListInsideScontrino: View { @State private var isAddFoodViewPresented = false @EnvironmentObject var foodData: FoodData var foodItems: [MyFoodItem] { foodData.foodItems } var body: some View { ZStack { // 背景色放在ZStack底层,不干扰上层List交互 Color.gray.opacity(0.100) if foodItems.isEmpty { VStack { Text("你的订单汇总将在添加菜品后显示在这里。") .font(.callout) .foregroundColor(.gray) .multilineTextAlignment(.center) .padding() Text("点击右下角按钮开始添加食物!") .font(.callout) .foregroundColor(.gray) } .padding() } else { List { ForEach(foodData.foodItems) { foodItem in FoodItemRow(foodItem: foodItem) .listRowSeparator(.hidden) } .onDelete(perform: deleteFoodItem) } .listStyle(InsetGroupedListStyle()) // 移除List自带背景,使用ZStack统一背景 .scrollContentBackground(.hidden) } } } private func deleteFoodItem(at offsets: IndexSet) { foodData.foodItems.remove(atOffsets: offsets) } } #Preview { ListInsideScontrino() .environmentObject(FoodData()) // 预览时注入环境对象 }
2. 调整ScontrinoView的布局与mask
给List设置完整可用空间,同时优化mask路径计算(避免直接依赖UIScreen尺寸):
import SwiftUI struct ScontrinoView: View { var body: some View { ZStack { ListInsideScontrino() .frame(maxWidth: .infinity, maxHeight: .infinity) // 让List占满可用空间 } .padding() .mask( GeometryReader { geo in Path { path in path.move(to: CGPoint(x: 0, y: 0)) let rowCount = Int(geo.size.height / 20) for i in 0..<rowCount { let x = CGFloat(i) * 20 path.addLine(to: CGPoint(x: x + 10, y: 30)) path.addLine(to: CGPoint(x: x + 20, y: 20)) } path.addLine(to: CGPoint(x: geo.size.width, y: geo.size.height)) path.addLine(to: CGPoint(x: 0, y: geo.size.height)) } .scaleEffect(CGSize(width: 1.0, height: -1.0)) } ) .shadow(radius: 5) .cornerRadius(15) .ignoresSafeArea() } }
3. 确保数据模型的响应式
确认FoodData中的foodItems使用@Published修饰,保证List能正确响应数据变化:
class FoodData: ObservableObject { @Published var foodItems: [MyFoodItem] = [] }
关键修改说明
- 把背景色移到ZStack底层,避免额外视图拦截List的触摸事件
- 给List添加
scrollContentBackground(.hidden),统一使用ZStack的背景色,避免List自带背景干扰 - 用
GeometryReader替代UIScreen.main.bounds计算mask路径,适配不同设备和布局 - 给List设置
frame(maxWidth: .infinity, maxHeight: .infinity),确保它获得足够的滚动空间
内容的提问来源于stack exchange,提问作者GiuAte
相关产品推荐
相关产品推荐

