iOS动画总结

View Animations

 UIView.animate(withDuration: 0.25,
                   delay: 0,
                   options: [],
                   animations: {

    }, completion: nil)

Animatable properties

  • bounds

  • frame

  • center

  • backgroundColor

  • alpha

  • transform

frame bounds transform之间的关系

  • frame: 当前相对父视图的坐标系的位置和大小

  • bounds:自身坐标系的位置和大小,觉得subViews的frame

  • transform 变换(位移动,缩放,旋转),transform改变时,会影响frame,不会影响bounds

Animation options: 详见 AnimationOptions

UIView.animate(withDuration: 0.5, delay: 0.4,
  options: .repeat,
  animations: {
    self.password.center.x += self.view.bounds.width
  },
  completion: nil
)

Animation easing

  • curveLinear: 匀速动画

  • .curveEaseIn: 动画开始时加速

  • .curveEaseOut: 动画结束时,减速

  • .curveEaseInOut: 动画开始时加速, 减速

SpringAnimations

UIView.animate(withDuration: 0.5, 
                       delay: 0.5,
        usingSpringWithDamping: 0.5, 
        initialSpringVelocity: 0.0,
        options: [],
        animations: {
          self.loginButton.center.y -= 30.0
          self.loginButton.alpha = 1.0
        }, completion: nil)
  • usingSpringWithDamping: 取值在 0 ~ 1.0,值越大,弹簧的刚度越大

  • initialSpringVelocity: 控制动画的初始速度。 值1.0设置动画的速度以覆盖动画的总距离(在一秒的跨度内)。 较大和较小的值将导致动画具有或多或少的速度。

TransitionAnimations

用于转场的动画Options

  • .transitionFlipFromLeft

  • .transitionFlipFromRight

  • .transitionCurlUp

  • .transitionCurlDown

  • .transitionCrossDissolve

  • .transitionFlipFromTop

  • .transitionFlipFromBottom

使用转场动画的场景:
  • 添加View时

    UIView.transition(with: animationContainerView,
                     duration: 0.33,
                     options: [.curveEaseOut, .transitionFlipFromBottom],
                     animations: {
                         self.animationContainerView.addSubview(newView)
                    },
                     completion: nil
     )
    
  • 移除View时

    UIView.transition(with: animationContainerView, 
                    duration: 0.33,
                     options: [.curveEaseOut, .transitionFlipFromBottom],
                  animations: {
                    self.newView.removeFromSuperview()
                  },
                  completion: nil
    )
    
  • 隐藏或显示View时

    UIView.transition(with: self.newView, 
                  duration: 0.33,
                   options: [.curveEaseOut, .transitionFlipFromBottom],
                 animations: {
                self.newView.isHidden = true
              },
                  completion: nil
    )
    
  • 替换View时

    UIView.transition(from: oldView, 
                        to: newView, 
                        duration: 0.33,
                        options: 
                        .transitionFlipFromTop,
                         completion: nil)
    

Keyframe

  • options: 详情查看UIViewKeyframeAnimationOptions
 UIView.animateKeyframes(withDuration: 1.5, delay: 0.0, animations: {
      //add keyframes
      UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.25, animations: {
        self.planeImage.center.x += 80.0
        self.planeImage.center.y -= 10.0
      })

      UIView.addKeyframe(withRelativeStartTime: 0.1, relativeDuration: 0.4) {
        self.planeImage.transform = CGAffineTransform(rotationAngle: -.pi / 8)
      }

      UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.25) {
        self.planeImage.center.x += 100.0
        self.planeImage.center.y -= 50.0
        self.planeImage.alpha = 0.0
      }

      UIView.addKeyframe(withRelativeStartTime: 0.51, relativeDuration: 0.01) {
        self.planeImage.transform = .identity
        self.planeImage.center = CGPoint(x: 0.0, y: originalCenter.y)
      }

      UIView.addKeyframe(withRelativeStartTime: 0.55, relativeDuration: 0.45) {
        self.planeImage.alpha = 1.0
        self.planeImage.center = originalCenter
      }
    }, completion: nil)

Layer Animations

View Animation 和 Layer Animation的区别

  • layer与View(就动画而言)不同,原因如下:

    • 图层是模型对象–它公开数据属性并且不实现任何逻辑。 它没有复杂的自动版式依赖性,也没有处理用户交互。

    • 它具有预定义的可见特征-这些特征是许多数据属性,它们会影响内容在屏幕上的呈现方式,例如边界线,边界颜色,位置和阴影。(预先会绘制一个layer)

    • Core Animation直接在GPU上优化了图层内容的缓存和快速绘制。

Views
  • 视图布局,层级复杂

  • 存在用户用户交互

  • 通常具有在CPU的主线程上执行的自定义逻辑或自定义绘图代码

  • 非常灵活,强大,有很多子类可以继承

Layers
  • 层次结构简单,布局解析速度快,绘制速度快。

  • 没有响应者链开销。

  • 默认情况下没有自定义逻辑。 并直接在GPU上绘制。

  • 不够灵活,子类继承较少

Layer动画流程

设置Layer动画时,控件本身本身不具有动画效果,当动画开始时,预先渲染的动画layer(presentation layer)将会替代控件,同时控件暂时隐藏,动画过程中不能交互

动画完成后 presentation layer 将从屏幕上删除,原始Layer再次显示自己。(动画结束需要更新layer的属性值为动画结束时的值)

Animation Properties

  • bounds

  • postion: position.x position.y

  • transform :transform.scale(x, y, z), transform.roate(x, y, z)

  • border: boorderWidth, backroudClolor, borderColor, corner

  • shadow: shadowOffset, shadowOpacity, shadowPath, shadowRadius

  • contents

  • mask

  • opacity

  • path

  • strokeEnd

  • strokeStart

let flyRight = CABasicAnimation(keyPath: "position.x")
flyRight.fromValue = -view.bounds.size.width / 2
flyRight.toValue = view.bounds.size.width / 2
flyRight.fillMode = .forwards
postion, anchorPoint, frame, bounds之间的区别
  • anchorPoint(锚点): 视图的几何操作(旋转,平移,缩放)的中心,

  • position 是相对layer的anchoorPoint 相对于superLayer的位置,即View的center

    postion.x = frame.origin.x + anchorPont.x * frame.width
    postion.y = frame.origin.y + anchorPont.y * frame.height
    
  • frame 当前layer相对superLayer的位置和大小, 最终由View体现

    frame.x = postion.x - anchorPont.x * frame.width
    frame.y = postion.y - anchorPont.y * frame.height
    
  • bounds 当layer自身的坐标系的位置和大小

    • 注意:当前改变了anchorPoint,frame会发生变化(尤其是在做transform动画时),但是position没有变化,所以一定要还原位移变化(手动改变center的值)

      extension UIView {
          func setAnchorPoint(_ point: CGPoint) {
              let oldOrigin = frame.origin
              layer.anchorPoint = point
              let newOrigin = frame.origin
              var transition: CGPoint = .zero
              transition.x = newOrigin.x - oldOrigin.x
              transition.y = newOrigin.y - oldOrigin.y
              center = CGPoint(x: center.x - transition.x,
                               y: center.y - transition.y)
      
             center = CGPoint(x: oldOrigin.x + layer.anchorPoint.x * frame.width ,
                               y:  oldOrigin.y + layer.anchorPoint.y * frame.height)
               /// center = CGPoint(x: oldOrigin.x + layer.anchorPoint.x     * frame.width, y:oldOrigin.y + layer.anchorPoint.y * frame.height)
          }
      }
      
fillMode
  • forwards: 动画结束停留在最后一帧

  • backwards:动画开始前,处于动画的第一帧

  • both:结合了forwards与backwards的特点,即动画开始前,处于动画的第一帧,动画结束停留在最后一帧

  • removed:动画结束,移除动画

CAAnimationGroup
let groupAnimation = CAAnimationGroup()
groupAnimation.beginTime = CACurrentMediaTime() + 0.5
groupAnimation.duration = 0.5
groupAnimation.fillMode = .backwards
group.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
let scaleDown = CABasicAnimation(keyPath: "transform.scale")s
caleDown.fromValue = 3.5
scaleDown.toValue = 1.0
let rotate = CABasicAnimation(keyPath: "transform.rotation")
rotate.fromValue = .pi / 4.0
rotate.toValue = 0.0
let fade = CABasicAnimation(keyPath: "opacity")fade.fromValue = 0.0
fade.toValue = 1.0
groupAnimation.animations = [scaleDown, rotate, fade]

Animation easing

  • EaseIn
    easeIn.png
  • EaseOut
    easeOut.png
  • EaseInEaseOut

    easeInEaseOut.png

More timing options

  • Repeating animations

    flyLeft.repeatCount = 4
    flyLeft.autoreverses = true
    
  • Change the animation speed

    flyLeft.speed = 2.0
    

Layer Springs - CASpringAnimation

  • damping: 阻尼系数, 阻止弹簧伸缩的系数,阻尼系数越大,停止越快

  • mass: 运动的质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大, 默认为1.0

  • stiffness: 刚度,默认为100,为正,为0时,弹性越软,值越大,弹性越硬

  • initialVelocity: 初始的速度,速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反

  • settlingDuration 估算时间 返回弹簧动画到停止时的估算时间,根据当前的动画参数估算

let jump = CASpringAnimation(keyPath: "position.y")
jump.initialVelocity = 100.0
jump.mass = 10.0
jump.stiffness = 1500.0
jump.damping = 50.0
jump.fromValue = textField.layer.position.y + 1.0
jump.toValue = textField.layer.position.y
jump.duration = jump.settlingDuration

let flash = CASpringAnimation(keyPath: "borderColor")
flash.damping = 7.0
flash.stiffness = 200.0
flash.fromValue = UIColor(red: 1.0, green: 0.27, blue: 0.0, alpha:
1.0).cgColor
flash.toValue = UIColor.white.cgColor
flash.duration = flash.settlingDuration
textField.layer.add(flash, forKey: nil)

Layer Keyframe Aniamtions - CAKeyframeAnimation

几个重要的属性

  • values: 动画的值

  • path:动画的路径

  • keyTimes:帧时长

  • timingFunctions:帧时间函数

  • calculationMode: 帧计算模式

let wobble = CAKeyframeAnimation(keyPath: "transform.rotation")
wobble.duration = 0.25
wobble.repeatCount = 4
wobble.values = [0.0, -.pi/4.0, 0.0, .pi/4.0, 0.0]
wobble.keyTimes = [0.0, 0.25, 0.5, 0.75, 1.0]
heading.layer.add(wobble, forKey: nil)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容

  • Core Animation其实是一个令人误解的命名。你可能认为它只是用来做动画的,但实际上它是从一个叫做Laye...
    小猫仔阅读 3,711评论 1 4
  • 在iOS实际开发中常用的动画无非是以下四种:UIView动画,核心动画,帧动画,自定义转场动画。 1.UIView...
    请叫我周小帅阅读 3,097评论 1 23
  • 如果想让事情变得顺利,只有靠自己--夏尔·纪尧姆 上一章介绍了隐式动画的概念。隐式动画是在iOS平台创建动态用户界...
    夜空下最亮的亮点阅读 1,940评论 0 1
  • 动画只是Core Animation特性的冰山一角 Core Animation功能 Core Animation...
    封楼阅读 336评论 0 0
  • 在iOS实际开发中常用的动画无非是以下四种:UIView动画,核心动画,帧动画,自定义转场动画。下面我们逐个介绍。...
    4b5cb36a2ee2阅读 355评论 0 0