SwiftUI中光标在水平ScrollView内时垂直滚动失效的解决方法
SwiftUI嵌套滚动手势传递问题
我在SwiftUI应用中实现了一个包含多个水平ScrollView(Row组件)的List,需求是既能垂直滚动浏览各个Row,又能在Row内部进行水平滚动。当前实现基础功能的代码如下:
struct Row: View { var body: some View { ScrollView(.horizontal) { HStack { ForEach(0..<100) { i in Text(String(i)) .padding(5) } } .padding(10) .background(.red) } } } struct ContentView: View { var body: some View { List(0..<100) {_ in Row() } .background(.blue) } }
问题描述
当光标处于Row的边界范围内时,外部List的垂直滚动会被禁用。我需要将Row的垂直滚动手势传递给外层List,让用户滚动List时,无需特意将光标移到Row范围外。
- 垂直滚动效果:光标在Row外时,List可正常垂直滚动
- 水平滚动效果:光标在Row内时,Row可正常水平滚动
- 问题示意图:光标在Row内时,拖动无法触发List的垂直滚动
解决方案
通过给水平ScrollView添加同时识别的拖拽手势,让垂直方向的手势能够被外层List接收,同时保留Row自身的水平滚动功能。修改后的Row代码如下:
struct Row: View { var body: some View { ScrollView(.horizontal) { HStack { ForEach(0..<100) { i in Text(String(i)) .padding(5) } } .padding(10) .background(.red) } // 添加同时识别的拖拽手势,让垂直手势传递给父视图 .simultaneousGesture( DragGesture(minimumDistance: 0, coordinateSpace: .global) .onChanged { _ in } ) } }
原理说明
simultaneousGesture修饰符允许当前视图的手势与父视图的手势同时被识别。这里添加的空拖拽手势会让垂直方向的触摸事件同时传递给外层List,从而实现光标在Row内时,依然可以触发List的垂直滚动,而Row的水平滚动功能不受影响。
内容的提问来源于stack exchange,提问作者Carpetfizz
相关产品推荐
相关产品推荐

