首页 > 解决方案 > SwiftUI | 如果被 ScrollView 取消,则从不调用 DragGestures onEnded

问题描述

我有以下问题。

我有一个我想拖动的View内部。ScrollView现在,一切正常,拖动和滚动也发生了。但是一旦我尝试两者都做,dragOffset似乎会留下来,而不是重置到它的初始位置。

更何况,onEnded永远DragGesture不会发生。我怎样才能阻止这种情况发生并将果岭重置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)
    }
}

谢谢!

标签: iosswiftswiftui

解决方案


解决方案是改用.updatingwith GestureState。在手势因某种原因取消后,它会自动将偏移量设置为其初始位置。

这样,我们就无需调用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)
    }
}

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

更新

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


推荐阅读