[英]SwiftUI | DragGestures onEnded never called if canceled by ScrollView
I have the following problem.我有以下问题。
I have a View
inside a ScrollView
that I want to drag.我在
ScrollView
中有一个要拖动的View
。 Now, everything works fine, the dragging occurs and the scrolling as well.现在,一切正常,发生拖动和滚动。 But once I try to do both, the
dragOffset
appears to stay, instead of resetting to its initial position.但是,一旦我尝试同时执行这两项操作,则
dragOffset
似乎会保持dragOffset
,而不是重置为其初始位置。
More so, onEnded
of the DragGesture
never happens.更
onEnded
是, DragGesture
onEnded
永远不会发生。 How can I stop this from happening and reset the green Rectangle
to its initial position?如何阻止这种情况发生并将绿色
Rectangle
重置为其初始位置?
Dragging or scrolling works just fine.拖动或滚动工作得很好。
But whenever I do both, this happens.但是每当我同时做这件事时,就会发生这种情况。
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)
}
}
Thank you!谢谢!
The solution is to use .updating
with GestureState
instead.解决方案是将
.updating
与GestureState
一起使用。 It automatically sets the offset to its initial position, after the gesture got canceled for whatever reason.无论出于何种原因取消手势后,它都会自动将偏移设置为其初始位置。
That way, we are independent of calling onEnded
to set it to its initial position which doesn't happen when you cancel the gesture by scrolling.这样,我们独立于调用
onEnded
将其设置为初始位置,当您通过滚动取消手势时不会发生这种情况。
Code:代码:
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)
}
}
Note: You can of course still have an onChanged
and onEnded
block, you just don't have to set the offset to .zero
any longer since it happens automatically.注意:您当然仍然可以有一个
onChanged
和onEnded
块,您只是不必.zero
偏移量设置为.zero
因为它会自动发生。
If you are to use it inside ObservableObject
class and want your dragOffset to be published, then here would be a solution I found .如果您要在
ObservableObject
类中使用它并希望发布 dragOffset,那么这将是我找到的解决方案。
I think scrollView
has its own gestures, such as UIScrollViewPanGestureRecognizer
in UIScrollView, to add a DragGesture
on scrollView
will confuse it.我认为
scrollView
有自己的手势,比如UIScrollViewPanGestureRecognizer
中的 UIScrollViewPanGestureRecognizer,在scrollView
上添加DragGesture
会混淆它。
you can change your code a little like:你可以稍微改变你的代码:
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)
}
I think it can work well.我认为它可以很好地工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.