SwiftUI中Form/Section内部视图的onDrop修饰符无法触发问题
问题原因
- SwiftUI 的
Form本质是使用 grouped 样式的List,iOS 端的 List 内置了行级拖拽重排序、滑动删除等高优先级系统手势,会优先拦截拖拽事件,不会透传给子视图自定义的onDrop代理 - Section 内的元素默认会被包装为列表行,列表行的命中测试默认优先响应自身的交互事件,即使子视图添加了
onDrop修饰符,事件也会被行容器拦截
解决方案
你可以根据需求选择任意一种方案修复:
- 若不需要 Form 的默认列表样式,直接把
Form替换为VStack,即可正常触发onDrop回调 - 若需要保留 Form 样式,给添加了
onDrop的视图添加.listRowDraggable(false)修饰符,禁用列表行自身的拖拽拦截能力,示例修改后的代码如下:
struct ContentView: View { @State private var text = "Goodbye" { didSet { print(text) } } var body: some View { Form { Section { Text(text) RoundedRectangle(cornerRadius: 10) .frame(width: 150, height: 150) .listRowDraggable(false) // 新增:禁用行拖拽拦截 .contentShape(Rectangle()) // 可选:明确命中测试范围,避免边缘区域无响应 .onDrop(of: ["text"], delegate: MyDropDelegate(text: $text)) } } } } struct MyDropDelegate: DropDelegate { @Binding var text: String // 主动实现校验逻辑,避免默认实现异常 func validateDrop(info: DropInfo) -> Bool { return info.hasItemsConforming(to: ["text"]) } func performDrop(info: DropInfo) -> Bool { self.text = "Received drop text" return true } }
内容的提问来源于stack exchange,提问作者Phantom59
相关产品推荐
相关产品推荐

