CALayer的mask属性(一个属性撑起一场动画)

最初知道这个属性还是在iOS核心动画高级技巧/视觉效果/图层蒙版看到的,然后随着对mask属性的了解,以及一些炫酷动画分析,原来很多炫酷的动画其实现原理竟那样简单。

现在回想以前看到的Twitter启动动画,我就呵呵一笑,其中就是用了CALayer的mask属性,它也是一个CALayer,所以就需要创建一个CALayer作为mask:

let maskLayer=CALayer()
maskLayer.contents=UIImage(named: "social-twitter-outline")?.CGImage
maskLayer.position=navigationController.view.center
maskLayer.bounds=CGRectMake(0, 0, 60, 60)
navigationController.view.layer.mask=maskLayer

此时,效果如图:

CALayer的mask属性(一个属性撑起一场动画)_第1张图片
twitter

然后给mask添加动画,先缩小一点,然后逐渐放大:

 //add animation
let twitterMaskAnimation:CAKeyframeAnimation=CAKeyframeAnimation(keyPath: "bounds")
twitterMaskAnimation.duration=1.0
twitterMaskAnimation.beginTime=CACurrentMediaTime()+1.0;//delay for a second
        
let initalBounds=NSValue(CGRect:maskLayer.bounds)
let secondBounds=NSValue(CGRect:CGRectMake(0, 0, 50, 50))//reduce some size
let finalBounds=NSValue(CGRect: CGRectMake(0, 0, 2000, 2000))
twitterMaskAnimation.values = [initalBounds,secondBounds,finalBounds]
twitterMaskAnimation.keyTimes=[0,0.5,1]
twitterMaskAnimation.timingFunctions=[CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut),CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut),CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)]
twitterMaskAnimation.removedOnCompletion=false
twitterMaskAnimation.fillMode=kCAFillModeForwards
       
navigationController.view.layer.mask?.addAnimation(twitterMaskAnimation, forKey: "twitterMaskAnimation")

此时的动画效果如下图:

CALayer的mask属性(一个属性撑起一场动画)_第2张图片
twitter animation

效果出来了有木有.

当然其中还有些效果不怎么好,在navigation.view和mask之间添加一个白色的背景,这样看起来会有一个非常好的过渡:

//add a maskBackgroundView with whiteColor
let maskBackgroudView:UIView=UIView.init(frame: navigationController.view.bounds)
maskBackgroudView.backgroundColor=UIColor.whiteColor()
navigationController.view.addSubview(maskBackgroudView)
navigationController.view.bringSubviewToFront(maskBackgroudView)

最后还需要添加一些其他的动画,maskBackgroundView逐渐消失以及给navigationController.view添加bounce的动画,看起来更加和谐一些:

//maskBackgroudView fade animation
UIView.animateWithDuration(0.1, delay: 1.35, options: UIViewAnimationOptions.CurveEaseIn, animations: { () -> Void in
     maskBackgroudView.alpha=0
}) { (finished:Bool) -> Void in
     maskBackgroudView.removeFromSuperview()
}
        
//navigationController.view bounce animation
UIView.animateWithDuration(0.25, delay: 1.3, options: UIViewAnimationOptions.TransitionNone, animations: { () -> Void in
       navigationController.view.transform=CGAffineTransformMakeScale(1.05, 1.05)
}) { (finished:Bool) -> Void in
     UIView.animateWithDuration(0.3, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
           navigationController.view.transform = CGAffineTransformIdentity
}, completion: { (finished:Bool) -> Void in
           navigationController.view.layer.mask=nil
   })
 }

实现最终效果如图:

CALayer的mask属性(一个属性撑起一场动画)_第3张图片
twitter splash

扩展:

使用CALayer的Mask实现注水动画效果:

使用CAShapeLayer来实现圆形图片加载动画[译]:

CALayer的mask属性(一个属性撑起一场动画)_第4张图片

你可能感兴趣的:(CALayer的mask属性(一个属性撑起一场动画))