繁体   English   中英

SwiftUI | 如果被 ScrollView 取消,则不会调用 DragGestures onEnded

[英]SwiftUI | DragGestures onEnded never called if canceled by ScrollView

我有以下问题。

我在ScrollView中有一个要拖动的View 现在,一切正常,发生拖动和滚动。 但是,一旦我尝试同时执行这两项操作,则dragOffset似乎会保持dragOffset ,而不是重置为其初始位置。

onEnded是, DragGesture onEnded永远不会发生。 如何阻止这种情况发生并将绿色Rectangle重置为其初始位置?

视觉表现

拖动或滚动工作得很好。

但是每当我同时做这件事时,就会发生这种情况。

演示代码

struct ContentView: View {
    
    @State private var dragOffset: CGSize = .zero
    
    
    var body: some View {
        ScrollView {
            Rectangle()
                .frame(width: UIScreen.main.bounds.size.width, height: 300)
                .foregroundColor(.green)
                .offset(x: dragOffset.width)
        }
        .gesture(DragGesture()
            .onChanged { value in
                dragOffset = value.translation
            }
            .onEnded { value in
                dragOffset = .zero
            }
        )
        .animation(.default)
    }
}

谢谢!

解决方案是将.updatingGestureState一起使用。 无论出于何种原因取消手势后,它都会自动将偏移设置为其初始位置。

这样,我们独立于调用onEnded将其设置为初始位置,当您通过滚动取消手势时不会发生这种情况。

代码:

struct ContentView: View {
    
    @GestureState private var dragOffset: CGSize = .zero
    
    
    var body: some View {
        ScrollView {
            Rectangle()
                .frame(width: UIScreen.main.bounds.size.width, height: 300)
                .foregroundColor(.green)
                .offset(x: dragOffset.width)
        }
        .gesture(DragGesture()
            .updating($dragOffset) { value, state, transaction in
                state = value.translation
            }
        )
        .animation(.default)
    }
}

注意:您当然仍然可以有一个onChangedonEnded块,您只是不必.zero偏移量设置为.zero因为它会自动发生。

更新

如果您要在ObservableObject类中使用它并希望发布 dragOffset,那么这将是我找到的解决方案

我认为scrollView有自己的手势,比如UIScrollViewPanGestureRecognizer中的 UIScrollViewPanGestureRecognizer,在scrollView上添加DragGesture会混淆它。

你可以稍微改变你的代码:

var body: some View {
    ScrollView {
        Rectangle()
            .frame(width: UIScreen.main.bounds.size.width, height: 300)
            .foregroundColor(.green)
            .offset(x: dragOffset.width, y: dragOffset.height)
            .gesture(DragGesture()
                .onChanged { value in self.dragOffset = value.translation }
                .onEnded { value in self.dragOffset = .zero }
        )
    }
    .animation(.default)
}

我认为它可以很好地工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM