SwiftUI中Section内嵌VStack时拖拽子元素触发整体拖拽如何解决
问题根因
Form 本质是基于 List 封装的布局容器,默认会把 Section 下的每个直接子视图识别为单个列表行,列表行自带的全局交互手势优先级高于内部子视图的自定义手势,所以你拖拽 VStack 内部元素时会触发整个VStack/Section的拖拽行为。
解决方案
只需要给嵌套的VStack添加修饰符,清除掉默认的列表行属性,同时给子元素指定明确的交互响应区域即可,修改后的代码如下:
enum TestData: String, CaseIterable { case one, two, three } struct ContentView: View { var body: some View { Form { Section { VStack(spacing: 12) { // 可自行调整子元素间距 ForEach(TestData.allCases.reversed(), id:\.self) { text in Text(text.rawValue) .frame(maxWidth: .infinity, alignment: .leading) // 撑满可用宽度,方便拖拽操作 .contentShape(Rectangle()) // 指定交互响应的精确区域 .onDrag { NSItemProvider(object: text.rawValue as NSString) } } } .listRowInsets(EdgeInsets()) // 移除系统默认的列表行内边距 .listRowBackground(Color.clear) // 移除系统默认的列表行背景样式 } Section { ForEach(TestData.allCases, id:\.self) { text in Text(text.rawValue) .onDrag { NSItemProvider(object: text.rawValue as NSString) } } } } } }
如果需要保留VStack默认的列表行卡片样式,也可以给每个子元素添加长按手势抢占响应优先级,在onDrag前添加以下修饰符即可:
.onLongPressGesture(minimumDuration: 0.2) {}
内容的提问来源于stack exchange,提问作者Phantom59
相关产品推荐
相关产品推荐

