繁体   English   中英

在 SwiftUI 视图上为 DragGesture 的 PredictedEndTranslation 设置动画

[英]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()
    }
}

通过 Github 运行的示例:SwiftUIPlayground

暂无
暂无

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

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