UIView动画 - 旋转和放大,然后旋转和缩小

时间:2017-05-04 19:22:50

标签: ios swift xcode rotation uiviewanimation

我有一个子类图像视图,我想淡入,放大和旋转,然后继续旋转,同时缩小和淡出。

我正在使用带有完成处理程序的UIView动画块来处理缩小的缩小。

问题在于它不是流畅的动画。在完成处理程序运行之前,动画会在再次运行之前停止。我需要它是一个很好的"猛扑"一部动画。

以下代码:

    let duration: TimeInterval = 3.0
    let rotate = CGAffineTransform(rotationAngle: CGFloat(Double.pi))


    UIView.animate(withDuration: duration * 3, delay: 0, options: [.curveLinear], animations: {
        // initial transform
        self.alpha = 0
        self.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
        // initial spin for duration of animaton
        UIView.animate(withDuration: duration * 3, delay: 0.0, options: [.curveLinear], animations: {
            self.transform = rotate
        }, completion: nil)

        // scaling and fading
        UIView.animate(withDuration: duration, delay: 0, options: [.curveLinear], animations: {
            UIView.setAnimationRepeatCount(3)
            self.transform = self.transform.scaledBy(x: 0.8, y: 0.8)
            self.alpha = 1
        }) { (true) in
            UIView.animate(withDuration: duration, animations: {
                UIView.setAnimationRepeatCount(3)
                self.transform = self.transform.scaledBy(x: 0.1, y: 0.1)
                self.alpha = 0
            })
        }
    }, completion: nil)

如何在缩小和缩小之前让动画在整个时间旋转,然后缩小和缩小?整个动画应持续3秒,并重复3次。感谢。

3 个答案:

答案 0 :(得分:4)

对于您修改过的请求,我正在使用块动画扩展您已经看到的内容。正如一些人所说,关键帧动画可能会更好,无论如何,这是思想。

创建一个动画,通过转换视图来旋转整个时间。 创建另一个动画,根据当前变换(旋转)进行缩放和淡化。在这个过程中,我刚刚创建了一些变量,允许您自定义(和重复)动画的各个部分。我把一些事情弄清楚了,并且知道我可以重构更简洁的事情。

这是代码

import UIKit

class OrangeView: UIView {



override func layoutSubviews() {
    super.layoutSubviews()

  let duration: TimeInterval = 9.0

  self.transform = CGAffineTransform.identity

  // initial transform
  self.alpha = 1
  self.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)

  // start rotation
  rotate(duration: duration)

  // scaling and fading
  scaleUpAndDown(desiredRepetitions: 3, initalDuration: duration)


  }

func rotate(duration: TimeInterval) {
                UIView.animate(withDuration: duration/2.0,
                               delay: 0.0,
                               options: [.curveLinear], animations: {
                                let angle = Double.pi
                                self.transform = self.transform.rotated(by: CGFloat(angle))
                }, completion: {[weak self] finished in
  guard let strongSelf = self else {
    return
  }
  if finished &&
    strongSelf.transform != CGAffineTransform.identity {
    strongSelf.rotate(duration: duration)
  } else {
    // rotation ending
  }
})

  }

func scaleUpAndDown(timesRepeated: Int = 0, desiredRepetitions: Int, initalDuration: TimeInterval) {

guard timesRepeated < desiredRepetitions,
  desiredRepetitions > 0, initalDuration > 0 else {
  self.transform = CGAffineTransform.identity
    return
}
let repeatedCount = timesRepeated + 1

let scalingDuration = initalDuration/2.0/Double(desiredRepetitions)

UIView.animate(withDuration: scalingDuration,
               delay: 0.0,
               animations: {
                let desiredOriginalScale: CGFloat = 0.8

                let scaleX = abs(CGAffineTransform.identity.a / self.transform.a) * desiredOriginalScale
                let scaleY = abs(CGAffineTransform.identity.d / self.transform.d) * desiredOriginalScale

                self.transform = self.transform.scaledBy(x: scaleX, y: scaleY)
                self.alpha = 1
              }) { (true) in
                UIView.animate(withDuration:scalingDuration,
                               delay: 0.0,
                               animations: {

                                let desiredOriginalScale: CGFloat = 0.1

                                let scaleX = abs(CGAffineTransform.identity.a / self.transform.a) * desiredOriginalScale
                                let scaleY = abs(CGAffineTransform.identity.d / self.transform.d) * desiredOriginalScale
                                  self.transform = self.transform.scaledBy(x: scaleX, y: scaleY)
                                  self.alpha = 0
                }) { finshed in
                  self.scaleUpAndDown(timesRepeated: repeatedCount, desiredRepetitions: desiredRepetitions, initalDuration: initalDuration);
                }
              }

  }

}

最后这是另一个动画gif

enter image description here

答案 1 :(得分:3)

enter image description here

我在onCompletion开始时看到旋转的轻微口吃。

我使用您的代码创建了缩减(在蓝色视图中显示如下)和橙色视图中的变体。这是从模拟器中获取并变成动画GIF,因此速度变慢。随着整个变换缩小,橙色视图继续旋转。

这是Orange View

的layoutSubviews()的代码

覆盖func layoutSubviews(){     super.layoutSubviews()

let duration: TimeInterval = 3.0
let rotate = CGAffineTransform(rotationAngle: CGFloat(Double.pi))

// initial transform
self.alpha = 0
self.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)

// initial spin for duration of animaton
UIView.animate(withDuration: duration,
               delay: 0.0,
               options: [.curveLinear],
               animations: {
                  self.transform = rotate;
                },
               completion: nil)
// scaling and fading
UIView.animate(withDuration: duration/2.0, animations: {
  self.transform = self.transform.scaledBy(x: 0.8, y: 0.8)
  self.alpha = 1
}) { (true) in
  UIView.animate(withDuration: duration/2.0, animations: {
    self.transform = self.transform.scaledBy(x: 0.1, y: 0.1)
    self.alpha = 0
  })
}

}

答案 2 :(得分:1)

尝试使用CGAffineTransformConcat()

  CGAffineTransform scale = CGAffineTransformMakeScale(0.8, 0.8);
  self.transform = CGAffineTransformConcat(CGAffineTransformRotate(self.transform, M_PI / 2), scale);