如何在SwiftUI的ScrollView中读取拖动位置?

如何在SwiftUI的ScrollView中读取拖动位置?,swiftui,Swiftui,我试图在连接到ScrollView的视图的Dragesture中读取位置,但ScrollView控制所有视图的Dragesture,不允许我读取这些信息。 下面是我的例子来说明这个问题, 我的目标是读取DragGesture中的拖动位置 使用新代码: struct ContentView: View { @State var locationY: CGFloat = .zero var body: some View {

我试图在连接到ScrollView的视图的Dragesture中读取位置,但ScrollView控制所有视图的Dragesture,不允许我读取这些信息。 下面是我的例子来说明这个问题, 我的目标是读取DragGesture中的拖动位置

使用新代码:

    struct ContentView: View {
    
    @State var locationY: CGFloat = .zero
    
    var body: some View {
        
        VStack
        {
            
            
            
            HStack
            {
                
                
                VStack
                {
                    Color.black.frame(height: 300)
                }
                .gesture( DragGesture().onChanged { value in locationY = value.location.y; print(locationY)} )
                
                
                
                
                ScrollView
                {
                    VStack
                    {
                        Color.blue.frame(height: 300)
                    }.background(GeometryReader {
                        Color.clear.preference(key: ViewOffsetKey.self,
                                               value: $0.frame(in: .global).origin.y)
                        // value: $0.frame(in: .named("scroll_area")).origin.y)
                    })
                }
                // .coordinateSpace(name: "scroll_area")
                .onPreferenceChange(ViewOffsetKey.self) {
                    self.locationY = $0
                    print(">> offset: \($0)")
                }
                .frame(height: 300)
                
                
            }
            
            Spacer()
            
        }
        
        
        
        
    }
}



struct ViewOffsetKey: PreferenceKey {
    typealias Value = CGFloat
    static var defaultValue = CGFloat.zero
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value += nextValue()
    }
}

下面是一个可能的解决方案,在后台使用
GeometryReader
读取视图的矩形(在任何需要的坐标空间中)和视图首选项,以便在顶层传递需要的坐标

使用Xcode 12.1/iOS 14.1进行测试

注:注释变量用于superview(即ScrollView)坐标

和助手首选项键

struct ViewOffsetKey: PreferenceKey {
    typealias Value = CGFloat
    static var defaultValue = CGFloat.zero
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value += nextValue()
    }
}

下面是一个可能的解决方案,在后台使用
GeometryReader
读取视图的矩形(在任何需要的坐标空间中)和视图首选项,以便在顶层传递需要的坐标

使用Xcode 12.1/iOS 14.1进行测试

注:注释变量用于superview(即ScrollView)坐标

和助手首选项键

struct ViewOffsetKey: PreferenceKey {
    typealias Value = CGFloat
    static var defaultValue = CGFloat.zero
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value += nextValue()
    }
}

对于Asperi:我在更新中使用了您的代码,但我在见证视图中获得了相同拖动的不同值,我如何使用您的代码获得与见证相同的答案默认情况下拖动手势使用
。本地
坐标空间,如果我正确理解您。是的,您是对的,区别在于在黑色rec上拖动会给出rec内正确的位置值,例如,如果我点击并拖动到顶部,它会给出0,直到下降300,但我无法通过您的代码获得蓝色rec的相同值,非常感谢您的帮助,即使在这一点上对Asperi:我在更新中使用了您的代码,但我确实在见证视图中获得了相同拖动的不同值,我如何使用您的代码获得与见证拖动手势相同的答案默认情况下使用
。如果我正确理解您的意思,本地
坐标空间。是的,您是对的,在黑色rec上拖动的差异将给出rec内部位置的正确值,例如,如果我点击并拖动到顶部,它将给出0,直到下降300,但我无法用您的代码获得蓝色的值,非常感谢您的帮助,即使到了这一点