【问题标题】:How to keep the initial animation running while a new one is performed?如何在执行新动画时保持初始动画运行?
【发布时间】:2021-03-22 07:59:14
【问题描述】:

我很难弄清楚这个动画的事情。问题是,.onAppear 摇晃动画(应该永远循环)在视图被拖动后立即停止并冻结(它有另一个动画,以便它平滑地移动到拖动位置)。

有没有办法让 onAppear 动画独立于被拖动的视图运行?需要注意的重要一点是,我确实需要依赖于数组的位置(因此拖动手势直接写入数据),而我不需要摆动(大小动画)完全绑定到数组。

动画在拖动时冻结的插图(不受欢迎 - 想要在被拖动期间和之后继续摆动)

请看代码:

   var body: some View {
        
      
            
       
        
        Circle()
           
          //  .resizable()
            .frame(width:size.width, height: size.height) //self.size is a state var
            .foregroundColor(color)
            .position(pos) //pos is a normal var bound to an array row
            .gesture(DragGesture()
            
                        .onChanged { gesture in
                        
                         withAnimation(.default) {
                            ballStorage.balls[numberInArray].position = gesture.location
                            }
                            
                            
                        }
                        .onEnded { gesture in
                          
                             ballStorage.checkOverlaps(for: numberInArray)
                           
                        }
                        
            ) .onAppear {
                
                withAnimation(Animation.easeInOut(duration: 1).repeatForever(autoreverses: true)) {
                    
                    size = CGSize(width: size.width+20, height: size.height+20)
                }
                
            }

        }
}

【问题讨论】:

  • 您能否发布视频或完整代码,以便我们了解您在做什么或您想要什么。
  • 也许只是重新添加动画 .onEnded 的 DragGesture() ?

标签: swift xcode animation swiftui


【解决方案1】:

你需要用自己的动画将圆圈分成自己的视图,然后内部动画将独立于外部动画。

这是关于以某种方式复制的代码的解决方案演示。使用 Xcode 12.1 / iOS 14.1 准备。

struct Ball: Identifiable, Hashable {
    let id = UUID()
    var position = CGPoint.zero
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

struct BallView: View {
    let ball: Ball
    var color = Color.blue
    @State private var size = CGSize(width: 40, height: 40)
    var body: some View {
        Circle()
            .frame(width:size.width, height: size.height) //self.size is a state var
            .animation(Animation.easeInOut(duration: 1).repeatForever(autoreverses: true), value: size)
            .foregroundColor(color)
            .onAppear {
                size = CGSize(width: size.width+20, height: size.height+20)
            }
    }
}

struct ContentView: View {
    @State private var balls = [Ball(position: CGPoint(x: 100, y: 100)), Ball(position: CGPoint(x: 100, y: 200))]
    @State private var off = CGSize.zero
    @State private var selected = -1
    var body: some View {
        
        ZStack {
            ForEach (Array(balls.enumerated()), id: \.1) { i, ball in
                BallView(ball: ball)
                    .offset(x: i == selected ? off.width : 0, y: i == selected ? off.height : 0)
                    .position(ball.position)
                    .gesture(DragGesture()
                        .onChanged { gesture in
                            self.selected = i
                            withAnimation(.default) {
                                self.off = gesture.translation
                            }
                        }
                        .onEnded { gesture in
                                let pt = balls[i].position
                                self.balls[i].position = CGPoint(x: pt.x + gesture.translation.width, y: pt.y + gesture.translation.height)
                                self.off = .zero
                                self.selected = -1
//                          ballStorage.checkOverlaps(for: numberInArray)
                        }
                    )
            }
        }
    }
}

【讨论】:

  • 太棒了,谢谢,没想到!每天学习...
  • 不,抱歉,当我将摆动动画放入您的示例中的子视图时,它实际上也会在拖动时停止。我想知道那里的主要区别是什么?此外,在您的代码中,它只允许拖动一定距离;这奇怪的尾随事情吗?每次移动都会创建新圈子吗?
  • 这不是关于分离动画,而是关于拖动(我最初没有接触)。分离动画的概念,即对原始问题的回答,没有改变——这是唯一的方法。看到更新了更正的拖动演示,但它只是演示,使演示适应您的代码是您的责任。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-06
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2023-04-09
  • 1970-01-01
相关资源
最近更新 更多