SwiftUI在Spring()动画完成后执行操作

hmae6n7t  于 11个月前  发布在  Swift
关注(0)|答案(2)|浏览(123)

我试图找出如何在SwiftUI中检测一个动画已经完成,具体来说:一个Spring()动画。(offset = .zero),但是这种方法有一个警告:Spring()动画会稍微超出它应该结束的点,然后反弹回来。所以“动画结束”会在动画结束之前被触发。
我做了一些研究,找到了另一种方法:SwiftUI withAnimation completion callback。然而,在这种解决方案中,动画对象的偏移量与原点进行比较,所以它与上面描述的问题相同。
我可以使用一个计时器,但这不是一个优雅的解决方案,因为Spring()动画的持续时间会根据它开始的位置动态变化,所以这不是方法。
在下面的示例中,我希望在动画完成后圆变为绿色。
有没有办法解决这个问题?谢谢帮助!
x1c 0d1x的数据

struct ContentView: View {
    
    @State var offset: CGSize = .zero
    @State var animationRunning = false
    
    var body: some View {
        
        VStack {
            Circle()
                .foregroundColor(self.animationRunning ? .red : .green)
                .frame(width: 200, height: 200)
                .offset(self.offset)
                .gesture(
                    DragGesture()
                        .onChanged{ gesture in
                            self.offset = gesture.translation
                    }
                    .onEnded{_ in
                        self.animationRunning = true
                        
                        withAnimation(.spring()){
                            self.offset = .zero
                        }
                })
            Spacer()
        }
    }
}

字符串

kcwpcxri

kcwpcxri1#

默认的动画持续时间(对于那些没有明确的持续时间参数的动画)通常是0.25-0.35(独立于它的启动位置和平台),所以在你的情况下,使用以下方法是完全安全的(用Xcode 11.4 / iOS 13.4测试):

withAnimation(.spring()){
    self.offset = .zero
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        self.animationRunning = false
    }
}

字符串

  • 注意:您可以调整0.5延迟,但对人眼来说差异并不显著。*
frebpwbc

frebpwbc2#

从iOS 17开始,现在可以向withAnimation调用添加完成

withAnimation(.spring()) {
    self.offset = .zero
} completion: {
    self.animationRunning = false
}

字符串

相关问题