Swift基础Swift - UI

Swift-UIView Animations、Transiti

2020-03-06  本文已影响0人  爱玩游戏的iOS菜鸟

Animations

在UIView中执行动画,将需要动画的属性放入animations闭包中即可

 UIView.animate(withDuration: 5.0) {
   self.parentV.backgroundColor = UIColor.red
   self.parentV.x = 40
   self.parentV.alpha = 0.5
   self.childV.width = 40
   UIView.performWithoutAnimation {//可以对其中需要变换的属性去掉动画
     self.childV.height = 40
   }
 }
UIVisualEffectView(毛玻璃效果)

UIVisualEffectView 的 effect 属性也可以动画:动画前设置为 nil,在animations: 中设置effect

  let effect = UIBlurEffect(style: .dark)
  let effectView = UIVisualEffectView(frame: CGRect(x: 15, y: 280, width: 50, height: 50))
  effectView.effect = nil
  view.addSubview(effectView)
  UIView.animate(withDuration: 3.0) {
    effectView.effect = effect
  }
UIView 动画 options

实际上UIView的动画还有很多参数可以配置

UIView.animate(withDuration:, delay: , options: , animations: , completion: )

其中参数:

下面是一些主要的options (UIView.AnimationOptions) :

  1. 动画执行过程速度的改变,会有一个加速度或者一个减速度。
  1. 动画执行次数
let parentFrame = parentV.frame
//设置自动往返
UIView.animate(withDuration: 2.0, delay: 1.0, options: UIView.AnimationOptions.autoreverse, animations: {
  UIView.setAnimationRepeatCount(5)//设置指定循环次数
  self.parentV.x = 50
  self.parentV.width = 50
  self.parentV.height = 50
  }, completion: { (complete) in
    self.parentV.frame = parentFrame//因为动画过程中,view的frame都已改变,所以在结束后需要重新赋原值
  })

设置无限重复,需要添加一个repeat

let opts: UIViewAnimationOptions = [.autoreverse , .repeat]
取消动画
self.parentV.layer.removeAllAnimations()
  finalFrame = CGRect(x: 50, y: parentV.y, width: parentV.width, height: parentV.height)
  UIView.animate(withDuration: 3.0, delay: 1.0, options: [.curveEaseIn], animations: {
    self.parentV.x = 50
    }, completion: { (complete) in
  })

记录用一个0.2秒的动画到终点,先拿到当前的位置。

  self.parentV.layer.position = self.parentV.layer.presentation()!.position
  self.parentV.layer.removeAllAnimations()
    UIView.animate(withDuration: 0.2) {
    self.parentV.frame = self.finalFrame
  }
transform也可以使用动画
  UIView.animate(withDuration: 5.0) {
    self.parentV.transform = CGAffineTransform.identity.translatedBy(x: -100, y: 0).rotated(by: 0.5).scaledBy(x: 0.5, y: 0.5)
  }
Spring 弹性动画
  UIView.animate(withDuration: 2.0, delay: 1.0, usingSpringWithDamping: 0.1, initialSpringVelocity: 5, options: [], animations: {
    self.parentV.x += 100
    self.parentV.width = 50
    self.parentV.height = 50
  }) { (complete) in

  }

其中的参数:

AnimateKeyframes 关键帧动画
let oringinFrame = parentV.frame
        var pFrame = oringinFrame
        var start = 0.0
        let count = 5
        let duration = 1.0 / 5.0
        
        let dx: CGFloat = -100
        let dy: CGFloat = 50
        var dir: CGFloat = 1

        UIView.animateKeyframes(withDuration: 4.0, delay: 2.0, options: [.autoreverse, .repeat], animations: {
            for _ in 0..<count{
                UIView.addKeyframe(withRelativeStartTime: start, relativeDuration: duration) {
                    pFrame.origin.x = dx * dir
                    pFrame.origin.y += dy
                    pFrame.size.width += dy * dir
                    pFrame.size.height += dy * dir
                    self.parentV.frame = pFrame
                }
                start += duration
                if start > 1.0 {
                    break
                }
                dir *= -1//换方向
            }
        }, completion: { (complete) in
            self.parentV.frame = oringinFrame
        })

其中的参数:

Transitions(过渡动画)

transition方法

过渡动画的类型options:

Transitions的2个重要方法:

  1. UIView.transition(with:, duration: , options: , animations, completion:)
    自定义View,并重写draw()方法
    注意:默认情况下,一个视图的子视图在transition动画期间改变layout,这个改变是不会有动画的,将在transition结束的时候直接改变,如果想要做动画改变,option需要加上.allowAnimatedContent
class CustomView: UIView {
  var reverse = false
  override func draw(_ rect: CGRect) {
    let f = self.bounds.insetBy(dx: 10, dy: 10)
    let context = UIGraphicsGetCurrentContext()
    if self.reverse {
      context?.strokeEllipse(in: f)
    }else{
      context?.stroke(f)
    }
  }
}
//点击翻转重绘
customV.reverse = !customV.reverse
        UIView.transition(with: customV , duration: 0.6 , options: .transitionFlipFromLeft , animations: {
            self.customV.setNeedsDisplay()
        }, completion: nil)
customV.reverse = !customV.reverse
        UIView.transition(with: customV , duration: 0.6 , options: [.transitionFlipFromLeft,.allowAnimatedContent] , animations: {
            self.flag = !self.flag
            let flagWidth = CGFloat(self.flag ? 20 : 50)
            self.customV.width = flagWidth
            self.customV.height = flagWidth
            self.customV.setNeedsDisplay()
        }, completion: nil)
  1. UIView.transition(from: , to:, duration:, options:, completion:)
    该方法需要两个view ,第一个会被第二个替换掉。整个transition动画会在他们的superview进行动画
  parentV.addSubview(customV)

  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let newCustomV = UILabel(frame: self.customV.frame)
    newCustomV.text = self.customV.text == "Hello" ? "World" : "Hello"
    newCustomV.textColor = UIColor.white
    newCustomV.sizeToFit()
    //翻转的是其superView(parentV)
    UIView.transition(from: self.customV , to: newCustomV , duration: 0.8 , options: .transitionFlipFromLeft , completion: { _ in
      self.customV = newCustomV
    })
  }
上一篇 下一篇

猜你喜欢

热点阅读