美文网首页坚持写iOS DeveloperiOS 开发
iOS核心动画高级技巧(笔记)——(七)显式动画

iOS核心动画高级技巧(笔记)——(七)显式动画

作者: gamper | 来源:发表于2016-08-21 21:04 被阅读132次

    属性动画

    • CABasicAnimation

    找到一篇很详细的CABasicAnimation使用总结

    • CAKeyframeAnimation

    CAKeyframeAnimation用values数组代替fromValuetoValue,里面的元素称为”关键帧“,动画对象会在指定的时间内,依次显示values数组中的每一个关键帧。
    path属性:可以设置一个CGPathRef、CGMutabelPathRef,让图层按照路径轨迹移动,path只对CALayeranchorPointposition起作用,如果设置了path,那么values将被忽略。
    keyTimes:可以为对应的关键帧指定对一个你的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的。
    rotationMode属性,设置它为常量kCAAnimationRotateAuto,图层将会根据曲线的切线自动旋转。

    动画组

    • CABasicAnimationCAKeyframeAnimation仅仅作用于单独的属性,而CAAnimationGroup可以把这些动画组合在一起。CAAnimationGroup是另一个继承于CAAnimation的子类,它添加了一个animations数组的属性,用来组合别的动画。
      let groupAnimation = CAAnimationGroup()
      groupAnimation.animations = [animation1,animation2]
      groupAnimation.duration = 4.0
      self.shipLayer.addAnimation(groupAnimation, forKey: nil)

    过渡

    • 有时候对于iOS应用程序来说,希望能通过属性动画来对比较难做动画的布局进行一些改变。比如交换一段文本和图片,或者用一段网格视图来替换,等等。属性动画只对图层的可动画属性起作用,所以如果要改变一个不能动画的属性(比如图片),或者从层级关系中添加或者移除图层,属性动画将不起作用。
      于是就有了过渡的概念。过渡并不像属性动画那样平滑地在两个值之间做动画,而是影响到整个图层的变化。过渡动画首先展示之前的图层外观,然后通过一个交换过渡到新的外观。
      为了创建一个过渡动画,我们将使用CATransition,同样是另一个CAAnimation的子类,和别的子类不同,CATransition有一个typesubtype来标识变换效果。
    • type属性是一个String类型,可以被设置成如下类型:
      kCATransitionFade
      kCATransitionMoveIn
      kCATransitionPush
      kCATransitionReveal
      除了这四种类型,可以通过一些别的方法来自定义过渡效果。默认的过渡类型是kCATransitionFade,当你在改变图层属性之后,就创建了一个平滑的淡入淡出效果。
      kCATransitionPush创建了一个新的图层,从边缘的一侧滑动进来,把旧图层从另一侧推出去的效果。
      kCATransitionMoveIn从顶部滑动进入,但不像推送动画那样把老图层推走。
      kCATransitionReveal把原始的图层滑动出去来显示新的外观,而不是把新的图层滑动进入。
    • 后面三种过渡类型都有一个默认的动画方向,它们都从左侧滑入,但是你可以通过subtype来控制它们的方向,提供了如下四种类型:
      kCATransitionFromRight
      kCATransitionFromLeft
      kCATransitionFromTop
      kCATransitionFromBottom
    • 过渡动画和之前的属性动画或者动画组添加到图层上的方式一致,都是通过-addAnimation:forKey:方法。但是和属性动画不同的是,对指定的图层一次只能使用一次CATransition。
    • 隐式过渡

    在自己创建的图层中对图层contents图片做的改动都会自动附上淡入淡出的动画,但是对于视图关联的图层,或者是其他隐式动画的行为,这个特性依然是被禁用的。

    • 对图层树的动画

    CATransition并不作用于指定的图层属性,可以在即使不能准确得知改变了什么的情况下对图层做动画,例如,在不知道UITableView哪一行被添加或者删除的情况下,直接就可以平滑地刷新它,或者在不知道UIViewController内部的视图层级的情况下对两个不同的实例做过渡动画。
    为了确保CATransition添加到的图层在过渡动画发生时不会在树状结构中被移除,一般来说,只需要将动画添加到被影响图层的superlayer

    • 自定义动画

    苹果通过UIView+transitionFromView:toView:duration:options:completion:+transitionWithView:duration:options:animations:方法提供了Core Animation的过渡特性。但是这里的可用的过渡选项和CATransitiontype属性提供的常量完全不同。UIView过渡方法中options参数可以由如下常量指定:
    UIViewAnimationOptionTransitionFlipFromLeft
    UIViewAnimationOptionTransitionFlipFromRight
    UIViewAnimationOptionTransitionCurlUp
    UIViewAnimationOptionTransitionCurlDown
    UIViewAnimationOptionTransitionCrossDissolve
    UIViewAnimationOptionTransitionFlipFromTop
    UIViewAnimationOptionTransitionFlipFromBottom
    CALayer有一个-renderInContext:方法,可以通过把它绘制到Core Graphics的上下文中捕获当前内容的图片,然后在另外的视图中显示出来。如果我们把这个截屏视图置于原始视图之上,就可以遮住真实视图的所有变化,于是重新创建了一个简单的过渡效果。
    renderInContext:创建自定义过渡效果
    @IBAction func start(sender: UIButton) {
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, true, 0.0)
    self.view.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let coverImage = UIGraphicsGetImageFromCurrentImageContext()
    //insert snapshot view in front of this one
    let coverView = UIImageView(image: coverImage)
    coverView.frame = self.view.bounds
    self.view.addSubview(coverView)
    //update the view (we'll simply randomize the layer background color)
    let red = CGFloat(arc4random()) / CGFloat(INT_MAX)
    let green = CGFloat(arc4random()) / CGFloat(INT_MAX)
    let blue = CGFloat(arc4random()) / CGFloat(INT_MAX)
    self.view.backgroundColor = UIColor(red: red, green: green, blue: blue, alpha: 1.0)
    //perform animation (anything you like)”
    UIView.animateWithDuration(1.0, animations: ({
    var transform = CGAffineTransformIdentity
    transform = CGAffineTransformMakeScale(0.01, 0.01)
    transform = CGAffineTransformRotate(transform,CGFloat(M_PI_2))
    coverView.transform = transform
    coverView.alpha = 0.0
    }), completion: { (finished:Bool) -> Void in coverView.removeFromSuperview()}
    )
    }

    使用renderInContext:创建自定义过渡效果
    这里有个警告:-renderInContext:捕获了图层的图片和子图层,但是不能对子图层正确地处理变换效果,而且对视频和OpenGL内容也不起作用。但是用CATransition,或者用私有的截屏方式就没有这个限制了。

    在动画过程中取消动画

    • 可以用-addAnimation:forKey:方法中的key参数来在添加动画之后检索一个动画,使用如下方法:- (CAAnimation *)animationForKey:(NSString *)key;但并不支持在动画运行过程中修改动画,所以这个方法主要用来检测动画的属性,或者判断它是否被添加到当前图层中。为了终止一个指定的动画,你可以用如下方法把它从图层移除掉:- (void)removeAnimationForKey:(NSString *)key,或者移除所有动画:- (void)removeAllAnimations
      动画一旦被移除,图层的外观就立刻更新到当前的模型图层的值。一般说来,动画在结束之后被自动移除,除非设置removedOnCompletionNO,如果你设置动画在结束之后不被自动移除,那么当它不需要的时候你要手动移除它;否则它会一直存在于内存中,直到图层被销毁。
      -animationDidStop:finished:方法中的flag参数表明了动画是自然结束还是被打断,如果被打断,它会打印NO,如果允许它完成,它会打印YES

    相关文章

      网友评论

        本文标题:iOS核心动画高级技巧(笔记)——(七)显式动画

        本文链接:https://www.haomeiwen.com/subject/mpeisttx.html