【问题标题】:SwiftUI multiple animations for same element同一元素的 SwiftUI 多个动画
【发布时间】:2020-12-23 09:10:22
【问题描述】:

我是 SwiftUI 新手,但我对 Storyboard 有很好的了解。

一开始我想从一些动画开始,但其中一个有问题:

  • 我希望图像从一开始的 0x0 变成 50x50 的大小。
  • 在 50x50 之后,它应该重复一个动画,使尺寸变为 50x50 -> 40x40 -> 50x50 -> ...永远

我知道@State 变量,.onAppear 事件,用autoreverse bool 重复动画,但我不知道如何使用它们成为最佳分辨率。

我希望有人可以帮助我。

@State var element_appeared : Bool = false

Image(systemName: "paperplane.fill")
  .resizable()
  .frame(width: element_appeared ? 50 : 0, height: element_appeared ? 50 : 0)
  .onAppear() {
    element_appeared.toggle()
}
  .animation(.easeInOut)

这就是动画一开始的工作方式。我认为我必须处理 element_appeared 变量,但我真的不知道如何..

【问题讨论】:

  • 您需要延迟第二次更改。接下来应该会有所帮助stackoverflow.com/a/65299904/12299030
  • 好的,首先我要感谢您的回答,但我是 SwiftUI 的新手,无法理解另一篇文章中的代码 :( 如何延迟第二个动画以及如何忽略第一个,在它成功之后?^^

标签: swift animation swiftui


【解决方案1】:

您可以创建一个枚举,因为您的动画有两个以上的状态。然后使用DispatchQueue延迟第二个动画。

这是一个演示:

enum AnimationState {
    case notAppeared, appeared, animating
}

struct ContentView: View {
    @State private var animationState: AnimationState = .notAppeared
    private let delay: TimeInterval = 1

    var body: some View {
        Image(systemName: "paperplane.fill")
            .resizable()
            .frame(width: imageSize, height: imageSize)
            .onAppear {
                withAnimation(.easeInOut(duration: delay)) {
                    animationState = .appeared
                }
                DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
                    withAnimation(Animation.easeInOut.repeatForever()) {
                        animationState = .animating
                    }
                }
            }
    }

    private var imageSize: CGFloat {
        switch animationState {
        case .notAppeared: return 0
        case .appeared: return 50
        case .animating: return 40
        }
    }
}

【讨论】:

    【解决方案2】:

    这是一个例子。我使用第二个@State 来管理不同的动画。

    @State var showIcon : Bool = false
    @State var animateForever: Bool = false
    
    var body: some View {
        Image(systemName: "paperplane.fill")
            .resizable()
            .frame(width: showIcon ? 50 : 0, height: showIcon ? 50 : 0)
            //.opacity(showIcon ? 1.0 : 0.0)
            .scaleEffect(animateForever ? 0.8 : 1.0) // 0.8 == 40/50
            .onAppear() {
                withAnimation(Animation.easeInOut(duration: 1.0)) {
                    showIcon.toggle()
                }
                
                DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                    withAnimation(Animation.easeInOut(duration: 1.0).repeatForever()) {
                        animateForever.toggle()
                    }
                }
            }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-15
      • 1970-01-01
      • 1970-01-01
      • 2020-03-23
      • 2020-05-12
      • 2011-06-17
      相关资源
      最近更新 更多