![](/img/trans.png)
[英]Adjusting the frame of a SwiftUI view with a DragGesture resizes it in all dimensions
[英]Animating to the predictedEndTranslation of a DragGesture on a SwiftUI view
我想在DragGesture
的预测位置放置一个视图,这就是我在.gestureEnded
闭包中.gestureEnded
,将更改包装在withAnimation
块中。 然而,当我在实时视图中尝试时,变化并没有动画化。
这是框架的错误还是我做错了什么?
struct ContentView: View {
@State var ty: CGFloat = 0
var dragGesture: some Gesture {
DragGesture()
.onChanged { theGesture in
self.ty = theGesture.translation.height
print("Changed")
}
.onEnded { theGesture in
print("Ended")
withAnimation(Animation.easeOut(duration: 3)) {
self.ty = theGesture.predictedEndTranslation.height
}
}
}
var body: some View {
VStack {
ForEach(1 ..< 5) { _ in
Color.red
.frame(minHeight: 20, maxHeight: 100)
.padding(0)
}
}
.transformEffect(.init(translationX: 0, y: ty))
.gesture(dragGesture)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
似乎translateEffect
不能动画。 这是有道理的,因为 CGAffineTransform 不符合Animatable
,所以这可能是预期的。 幸运的是,您仍然可以使用.offset(x: 0, y: ty)
。
这对你有用吗?
请注意,某些动画(如这个)在 Xcode Live Preview 中不起作用。 您需要在设备或模拟器上运行它。
SwiftUI/iOS 13.4 效果的示例实现,还修复了重复拖动时视图跳跃的问题。
诀窍是使用@GestureState
来跟踪正在进行的手势并单独保持整体状态变化,使用.offset
修饰符应用更改:
struct DragGestureView: View {
@GestureState var dragOffset = CGSize.zero
@State var offset: CGFloat = 0
var dragGesture: some Gesture {
DragGesture()
.updating($dragOffset) { value, state, _ in
state = value.translation
}
.onEnded { gesture in
// keep the offset already moved without animation
self.offset += gesture.translation.height
withAnimation(Animation.easeOut(duration: 3)) {
self.offset += gesture.predictedEndTranslation.height - gesture.translation.height
}
}
}
var body: some View {
VStack {
ForEach(1 ..< 5) { _ in
Color.red
.frame(minHeight: 20, maxHeight: 100)
}
}
.offset(x: 0, y: offset + dragOffset.height)
.gesture(dragGesture)
}
}
struct DragGestureView_Previews: PreviewProvider {
static var previews: some View {
DragGestureView()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.