ios - SwiftUI 动画 : How to stagger repeating animation with delay

标签 ios swift animation swiftui

尝试在 SwiftUI 中实现以下动画并发现这是不可能的:

enter image description here

总结一下效果:一个重复的脉冲,以交错的延迟为每个片段设置动画。对于每个分割市场:

  • 从不透明度 = 0.5 开始,比例 = 1
  • 动画不透明度=1.0,比例=1.3
  • 动画曲线开始快速,缓出时间更长

  • 此外,每个“脉冲”之间都有延迟。

    我使用 SwiftUI 能够做到的最接近的是使用 .repeatForever 连续重复的动画。修饰符。 (下面的代码。暂时忽略时间不匹配。)

    如何在动画的每个循环之间添加延迟?

    下面是我的代码的结果:

    enter image description here
    import SwiftUI
    
    struct ArrowShape : Shape {
    
        func path(in rect: CGRect) -> Path {
            var path = Path()
    
            path.move(to: CGPoint(x: 0, y: 0))
            path.addLine(to: CGPoint(x: rect.size.width, y: rect.size.height/2.0))
            path.addLine(to: CGPoint(x: 0, y: rect.size.height))
    
            return path
        }
    }
    
    struct Arrows: View {
        private let arrowCount = 3
    
        @State var scale:CGFloat = 1.0
        @State var fade:Double = 0.5
    
        var body: some View {
    
            ZStack {
                Color(red: 29.0/255.0, green: 161.0/255.0, blue: 224.0/255.0).edgesIgnoringSafeArea(.all)
    
                HStack{
                    ForEach(0..<self.arrowCount) { i in
                        ArrowShape()
                            .stroke(style: StrokeStyle(lineWidth: CGFloat(10),
                                                      lineCap: .round,
                                                      lineJoin: .round ))
                            .foregroundColor(Color.white)
                            .aspectRatio(CGSize(width: 28, height: 70), contentMode: .fit)
                            .frame(maxWidth: 20)
                            .animation(nil)
                            .opacity(self.fade)
                            .scaleEffect(self.scale)
                            .animation(
                                Animation.easeOut(duration: 0.8)
                                .repeatForever(autoreverses: true)
                                .delay(0.2 * Double(i))
                            )
                    }
                }
    
                .onAppear() {
                    self.scale = 1.2
                    self.fade = 1.0
                }
            }
        }
    }
    
    
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            Arrows()
        }
    }
    

    最佳答案

    我认为你可以使用 Timer 和 DispatchQueue 来实现它,试试这个,看看它是否按你想要的方式工作

    struct Arrows: View {
        private let arrowCount = 3
    
        let timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
    
        @State var scale:CGFloat = 1.0
        @State var fade:Double = 0.5
    
        var body: some View {
    
            ZStack {
                Color(red: 29.0/255.0, green: 161.0/255.0, blue: 224.0/255.0).edgesIgnoringSafeArea(.all)
    
                HStack{
                    ForEach(0..<self.arrowCount) { i in
                        ArrowShape()
                            .stroke(style: StrokeStyle(lineWidth: CGFloat(10),
                                                      lineCap: .round,
                                                      lineJoin: .round ))
                            .foregroundColor(Color.white)
                            .aspectRatio(CGSize(width: 28, height: 70), contentMode: .fit)
                            .frame(maxWidth: 20)
                            .animation(nil)
                            .opacity(self.fade)
                            .scaleEffect(self.scale)
                            .animation(
                                Animation.easeOut(duration: 0.5)
                                //.repeatForever(autoreverses: true)
                                .repeatCount(1, autoreverses: true)
                                .delay(0.2 * Double(i))
                            )
                    }.onReceive(self.timer) { _ in
                         self.scale = self.scale > 1 ?  1 : 1.2
                         self.fade = self.fade > 0.5 ? 0.5 : 1.0
                         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                                    self.scale = 1
                                    self.fade = 0.5
                                }
                        }
                }
            }
        }
    }
    

    关于ios - SwiftUI 动画 : How to stagger repeating animation with delay,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60852328/

    相关文章:

    swift - tableView 中的约束动画问题

    android - 在 Android 中启动一个 AnimationDrawable

    ios - 如何以编程方式截取可扩展uitableview的屏幕截图

    ios - AVCaptureSession - 在帧的特定部分内进行捕获

    ios - 当显示删除确认按钮时,UITableViewCell.showingDeleteConfirmation 给出 NO

    ios - 使用 UIViewController 动画显示 UINavigationController

    ios - 获取碰撞点时遇到问题

    ios - SWIFT ABI 在哪里出现?

    objective-c - 用反射修改字符串

    Angular2 Animation Transitions 仅针对某些事件触发