iOS Layer动画 二(Swift)

来源:互联网 发布:知乎你见过最阴暗的事 编辑:程序博客网 时间:2024/04/30 03:33

本文内容来自raywenderlich的Intermediate iOS Animation,记录下学些的内容。

iOS Layer动画 二(Swift)

Layer 弹簧动画(Layer Springs)

需要使用到CASpringAnimation,关于CASpringAnimation请参考iOS9 CASpringAnimation 弹簧动画详解,相关属性如下:

  • damping 阻尼系数,默认值为10
  • mass 质量,默认值为1
  • stiffness 刚度系数,默认值为100
  • initialVelocity 初始速率,默认值为0
  • settlingDuration 返回弹簧动画到停止时的估算时间

示例的效果如下:

弹簧动画

代码如下:

  func presentationAnimations() {    let flyRight = CASpringAnimation(keyPath: "position.x")    flyRight.damping = 250    flyRight.mass = 50.0    flyRight.stiffness = 800    flyRight.initialVelocity = 1.0    flyRight.fromValue = -view.bounds.size.width/2    flyRight.toValue = view.bounds.size.width/2    flyRight.duration = flyRight.settlingDuration    flyRight.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)    //flyRight.speed = 1.5    flyRight.fillMode = kCAFillModeBackwards    flyRight.delegate = self    flyRight.setValue("form", forKey: "name")    flyRight.setValue(heading.layer, forKey: "layer")    heading.layer.addAnimation(flyRight, forKey: nil)    flyRight.beginTime = CACurrentMediaTime() + 0.33    flyRight.setValue(username.layer, forKey: "layer")    username.layer.addAnimation(flyRight, forKey: nil)    flyRight.beginTime = CACurrentMediaTime() + 0.5    flyRight.setValue(password.layer, forKey: "layer")    password.layer.addAnimation(flyRight, forKey: nil)    animateLoginButton()    animateInfo()    animateCloud(cloud1.layer)    animateCloud(cloud2.layer)    animateCloud(cloud3.layer)    animateCloud(cloud4.layer)  }

Layer关键帧(Layer Keyframes)

使用CAKeyframeAnimation,用到属性有:

  • keyTimes 可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0
  • values 关键帧数组

实例效果如下,气球balloon运动:

关键帧动画

代码如下:

//热气球动画func animateHotAirBalloon()  {    let balloon = CALayer()    balloon.contents = UIImage(named: "balloon")?.CGImage    balloon.frame = CGRect(x: -50.0, y: 0.0, width: 50.0, height: 65.0)    view.layer.insertSublayer(balloon, below: username.layer)    let flight = CAKeyframeAnimation(keyPath: "position")    flight.duration = 12.0    flight.keyTimes = [0, 0.5, 1.0]    flight.values = [        CGPoint(x: -50.0, y: 0.0),        CGPoint(x: view.frame.width+50, y: 160.0),        CGPoint(x: -50.0, y: view.frame.size.height/2)        ].map{NSValue(CGPoint: $0)}    balloon.addAnimation(flight, forKey: nil)}

Shape和Mask动画(Shape And Mask Animations)

动画作用与CAShapeLayerpath

动画效果如下,连个AvatarView左右往返运动,在相遇时有个形变的过程:

Shape和Mask动画

主要代码如下:

  func bounceOffPoint(bouncePoint: CGPoint, morphSize: CGSize) {    let originalCenter = center    //前进到bouncePoint的位置    UIView.animateWithDuration(animationDuration, delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.0, options: [], animations: {      self.center = bouncePoint      }, completion: {_ in        //complete bounce    })    //返回到original位置    UIView.animateWithDuration(animationDuration, delay: animationDuration, usingSpringWithDamping: 0.7, initialSpringVelocity: 1.0, options: [], animations: {      self.center = originalCenter      }, completion: {_ in        delay(seconds: 0.1) {          if self.keepAnimating {            self.bounceOffPoint(bouncePoint, morphSize: morphSize)          }        }    })    var morphRect = CGRect(x: 0.0, y: bounds.size.height-morphSize.height,                           width: morphSize.width, height: morphSize.height)    //左边的avtar    if originalCenter.x < bouncePoint.x {        morphRect.origin.x = bounds.width - morphSize.width    }    let morph = CABasicAnimation(keyPath: "path")    morph.duration = animationDuration    morph.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)    morph.toValue = UIBezierPath(ovalInRect: morphRect).CGPath    circleLayer.addAnimation(morph, forKey: nil)    maskLayer.addAnimation(morph, forKey: nil)  }

最后可以添加上,使avtar由circle编程square的动画:

func toSquare() {    keepAnimating = false    let squarePath = UIBezierPath(rect: bounds).CGPath    let ovalPath = UIBezierPath(ovalInRect: bounds).CGPath    maskLayer.path = squarePath    circleLayer.path = squarePath    let morph = CABasicAnimation(keyPath: "path")    morph.fromValue = ovalPath    morph.toValue = squarePath    morph.duration = 0.2    maskLayer.addAnimation(morph, forKey: nil)    circleLayer.addAnimation(morph, forKey: nil)}

渐变动画(Gradient Animations)

渐变要使用CAGradientLayer,动画改变的是locations

最开始设置gradientLayer,如下:

let gradientLayer = CAGradientLayer()// Configure the gradient heregradientLayer.backgroundColor = UIColor.whiteColor().CGColorgradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)gradientLayer.locations = [0.25, 0.5, 0.75]gradientLayer.colors = [    UIColor.blackColor(),    UIColor.whiteColor(),    UIColor.blackColor()    ].map{ color in color.CGColor }

刚开始效果如下:

初始效果

然后,调整gradientLayer的frame,并添加动画,再设置maskView,最终的效果如下:

渐变动画

代码如下:

  override func didMoveToWindow() {    super.didMoveToWindow()    gradientLayer.frame = bounds    layer.addSublayer(gradientLayer)    gradientLayer.frame = CGRect(        x: -bounds.size.width,        y: bounds.origin.y,        width: 3 * bounds.size.width,        height: bounds.size.height    )    let gradientAniamtion = CABasicAnimation(keyPath: "locations")    gradientAniamtion.fromValue = [0.0, 0.0, 0.25]    gradientAniamtion.toValue = [0.75, 1.0, 1.0]    gradientAniamtion.duration = 3.0    gradientAniamtion.repeatCount = Float.infinity    gradientLayer.addAnimation(gradientAniamtion, forKey: nil)    maskView = UIImageView(image: imageWithText(text))  }

可以设置多种颜色

gradientLayer.locations = [0.0, 0.0, 0.0, 0.0, 0.0, 0.25]gradientLayer.colors = [    UIColor.yellowColor(),    UIColor.greenColor(),    UIColor.orangeColor(),    UIColor.cyanColor(),    UIColor.redColor(),    UIColor.yellowColor()    ].map {color in color.CGColor}gradientAniamtion.fromValue = [0.0, 0.0, 0.0, 0.0, 0.0, 0.25]gradientAniamtion.toValue = [0.65, 0.8, 0.85, 0.9, 0.95, 1.0]

效果如下:

多彩渐变

Stroke动画(Stroke Animations)

主要用到了strokeEndstrokeStart

开始下拉时,改变ovalShapeLayerstrokeEnd,来绘制一个整圆:

ovalShapeLayer.strokeEnd = progress

开始刷新,动画代码如下:

let strokeEndAnimation = CABasicAnimation(keyPath: "strokeEnd")strokeEndAnimation.fromValue = 0.0strokeEndAnimation.toValue = 1.0let strokeStartAnimation = CABasicAnimation(keyPath: "strokeStart")strokeStartAnimation.fromValue = -0.5strokeStartAnimation.toValue = 1.0let strokeGroup = CAAnimationGroup()strokeGroup.duration = 1.5strokeGroup.repeatDuration = 5.0strokeGroup.animations = [strokeStartAnimation, strokeEndAnimation]ovalShapeLayer.addAnimation(strokeGroup, forKey: nil)

动画效果如下:

stroke动画

0 0
原创粉丝点击