SwiftUI列表内部无法滚动求助:保留手势与onDelete的解决方案
SwiftUI List滚动异常修复:保留手势同时恢复滚动功能
问题根源
你遇到的滚动失效问题,是因为onTapGesture这类默认手势修饰符会独占触摸事件——当触摸列表元素时,点击手势会优先被识别,直接阻断了List原生的滚动手势响应。
解决方案
将所有自定义手势(包括点击、长按)都通过simultaneousGesture添加,该修饰符允许多个手势同时被识别,既保留自定义手势功能,又不影响List的滚动。
修改后的代码
List { ForEach(fetchRequest, id: \.self) { task in Text(task.desc!) .foregroundColor(task.done ? .white : task.today ? .white : .black) .listRowBackground(task.done ? Color.green : task.today ? Color.blue : Color.white) // 将onTapGesture替换为simultaneousGesture包裹的TapGesture .simultaneousGesture(TapGesture().onEnded { self.taskToEdit = task }) .swipeActions(allowsFullSwipe: true) { Button(role: .cancel) { task.done.toggle() task.today = false task.date_completion = Date() do {try viewContext.save()} catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } print("mark as done") } label: { Label("Done", systemImage: "checkmark") } .tint(.green) } .simultaneousGesture(LongPressGesture() .onEnded { _ in let impactMed = UIImpactFeedbackGenerator(style: .light) impactMed.impactOccurred() task.today.toggle() do {try viewContext.save()} catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } print("Loooong") print(task.today) } ) } .onDelete(perform: deleteItems) } //.listRowSeparator(.hidden) //.listRowInsets(.init(top: 4, leading: 8, bottom: 4, trailing: 8)) .sheet(item: self.$taskToEdit, content: { taskToEdit in itemDetail(taskItem: taskToEdit, textFieldText: taskToEdit.detail ?? "") })
补充说明
simultaneousGesture不会改变手势的触发逻辑,只是允许它和其他手势(比如List的滚动)同时被系统识别- 如果你需要让某个手势优先于滚动,可以使用
highPriorityGesture,但这种情况会再次阻断滚动,仅在特殊场景使用
内容的提问来源于stack exchange,提问作者Nat Serrano
相关产品推荐
相关产品推荐

