SwiftUI 动画和随后的反向动画到原始状态
Posted
技术标签:
【中文标题】SwiftUI 动画和随后的反向动画到原始状态【英文标题】:SwiftUI animation and subsequent reverse animation to original state 【发布时间】:2020-05-23 12:17:48 【问题描述】:我正在使用 SwiftUI,并且我想在视图出现后立即为其设置动画(动画的显式类型无关紧要),以便在我的应用程序中进行演示。 假设我只想放大我的视图,然后再次将其缩小到原来的大小,我需要能够将视图设置为新状态并在之后立即恢复到原始状态。 这是我到目前为止尝试过的示例代码:
import SwiftUI
import Combine
struct ContentView: View
@State private var shouldAnimate = false
private var scalingFactor: CGFloat = 2
var body: some View
Text("hello world")
.scaleEffect(self.shouldAnimate ? self.scalingFactor : 1)
.onAppear
let animation = Animation.spring().repeatCount(1, autoreverses: true)
withAnimation(animation)
self.shouldAnimate.toggle()
显然这并不能完全满足我的要求,因为let animation = Animation.spring().repeatCount(1, autoreverses: true)
仅通过使用平滑的autoreverse = true
设置来确保动画(到新状态)正在重复,这仍然会导致视图处于最终状态缩放到scalingFactor
。
所以我在animation
上也找不到任何属性,它可以让我的动画自动恢复到原始状态(在第一个动画之后我不必与视图交互),我也没有找到任何关于如何确定第一个动画何时真正完成,以便能够触发新动画。
我发现在某些视图的外观上制作动画是很常见的做法,例如只是为了展示这个视图可以交互,但最终不会改变视图的状态。例如,在按钮上设置弹跳效果动画,最终将按钮设置回其原始状态。当然,我找到了几个解决方案,建议与按钮交互以触发反向动画回到其原始状态,但这不是我想要的。
【问题讨论】:
【参考方案1】:这是一个基于ReversingScale
动画修饰符的解决方案,来自this my answer
使用 Xcode 11.4 / ios 13.4 测试
struct DemoReverseAnimation: View
@State var scalingFactor: CGFloat = 1
var body: some View
Text("hello world")
.modifier(ReversingScale(to: scalingFactor, onEnded:
DispatchQueue.main.async
self.scalingFactor = 1
))
.animation(.default)
.onAppear
self.scalingFactor = 2
【讨论】:
在此基础上:如果想要平滑的反向动画,我们可以将self.scalingFactor = 1
包裹在 withAnimation
块中:DispatchQueue.main.async withAnimation self.scalingFactor = 1
【参考方案2】:
如果您定义动画应该花费多长时间,另一种可行的方法:
struct ContentView: View
@State private var shouldAnimate = false
private var scalingFactor: CGFloat = 2
var body: some View
Text("hello world")
.scaleEffect(self.shouldAnimate ? self.scalingFactor : 1)
.onAppear
let animation = Animation.easeInOut(duration: 2).repeatCount(1, autoreverses: true)
withAnimation(animation)
self.shouldAnimate.toggle()
DispatchQueue.main.asyncAfter(deadline: .now() + 2)
withAnimation(animation)
self.shouldAnimate.toggle()
【讨论】:
这么好的解决方案。非常感谢。以上是关于SwiftUI 动画和随后的反向动画到原始状态的主要内容,如果未能解决你的问题,请参考以下文章