概述

今天要说的UIViewPropertyAnimator, 是iOS10新的API

详细

基础动画, 核心动画到自定义转场动画其实都不是什么新东西了, 所以我也是草草看一遍就能够读个大概, 但今天要说的UIViewPropertyAnimator, 是iOS10新的API, 其他的好处我还不太清楚, 但抽象动画逻辑和监控动画的进程上真的是方便很多。

一、准备工作

对于属性动画来说, 真的是个新知识, 想必会用的还不多, 我也是近期才有涉及, 理解不周还望大伙指点一二, 之前我们要做一些稍微高级的动画都会使用核心动画的方法, 但是核心动画有一个致命的弱点, 就是假象和被打断, 所以iOS10出了新的API真的是造福我们这些开发者. 不多说, 先了解新的API:

@available(iOS 10.0, *)
open class UIViewPropertyAnimator : NSObject, UIViewImplicitlyAnimating, NSCopying
@NSCopying open var timingParameters: UITimingCurveProvider? { get }
open var duration: TimeInterval { get }
open var delay: TimeInterval { get }
open var isUserInteractionEnabled: Bool
open var isManualHitTestingEnabled: Bool
open var isInterruptible: Bool
  • timingParameters: 时间参数

  • duration: 持续时间

  • delay: 延迟时间

  • isUserInteractionEnabled: 是否可交互

  • isManualHitTestingEnabled: 是否启动手动测试

  • isInterruptible: 是否可被打断

构造方法:

public init(duration: TimeInterval, timingParameters parameters: UITimingCurveProvider)
  • duration: 持续时间

  • timingParameters: 时间参数

public convenience init(duration: TimeInterval, curve: UIViewAnimationCurve, animations: (@escaping () -> Swift.Void)? = nil)
  • duration: 持续时间

  • curve: 动画曲线

  • animations: 动画执行闭包

public convenience init(duration: TimeInterval, controlPoint1 point1: CGPoint, controlPoint2 point2: CGPoint, animations: (@escaping () -> Swift.Void)? = nil)
  • duration: 持续时间

  • controlPoint1: 控制点1

  • controlPoint2: 控制点2

  • animations: 动画执行闭包

public convenience init(duration: TimeInterval, dampingRatio ratio: CGFloat, animations: (@escaping () -> Swift.Void)? = nil)
  • duration: 持续时间

  • dampingRatio: 减震比率

  • animations: 动画执行闭包

运行属性动画方法:

open class func runningPropertyAnimator(withDuration duration: TimeInterval, delay: TimeInterval, options: UIViewAnimationOptions = [], animations: @escaping () -> Swift.Void, completion: (@escaping (UIViewAnimatingPosition) -> Swift.Void)? = nil) -> Self
  • duration: 持续时间

  • options: 动画选项

  • animations: 动画执行闭包

  • completion: 动画完成闭包

添加动画组方法:

open func addAnimations(_ animation: @escaping () -> Swift.Void, delayFactor: CGFloat)
  • animation: 动画执行闭包

  • delayFactor: 延迟比率, 按照百分比计算 范围0~1

动画组完成方法:

open func addCompletion(_ completion: @escaping (UIViewAnimatingPosition) -> Swift.Void)
  • completion: 完成执行闭包

继续动画方法:

open func continueAnimation(withTimingParameters parameters: UITimingCurveProvider?, durationFactor: CGFloat)
  • withTimingParameters: 时间参数

  • durationFactor: 持续比率, 按照百分比计算 范围0~1

动画状态:

@available(iOS 10.0, *)
public enum UIViewAnimatingState : Int {
case inactive // The animation is not executing.
case active // The animation is executing.
case stopped // The animation has been stopped and has not transitioned to inactive.
}

动画位置:

@available(iOS 10.0, *)
public enum UIViewAnimatingPosition : Int {
case end
case start
case current
}

动画协议:

public protocol UIViewAnimating : NSObjectProtocol
@available(iOS 10.0, *)
public var state: UIViewAnimatingState { get }
public var isRunning: Bool { get }
public var isReversed: Bool { get set }
public var fractionComplete: CGFloat { get set }
public func startAnimation()
public func startAnimation(afterDelay delay: TimeInterval)
public func pauseAnimation()
public func stopAnimation(_ withoutFinishing: Bool)
@available(iOS 10.0, *)
public func finishAnimation(at finalPosition: UIViewAnimatingPosition)
  • state: 动画状态

  • isRunning: 动画是否在执行

  • isReversed: 动画是否反向执行

  • fractionComplete: 分段完成 范围0~1

  • startAnimation: 开始执行动画

  • startAnimation(afterDelay:): 延迟执行动画

  • pauseAnimation: 暂停动画执行

  • finishAnimation: 完成动画知悉在某个动画位置

二、实战实例

这次的API有点多, 因为本人也是第一次接触所以把每个都尝试了一遍, 我们就来使用这些API进行实战, 和之前一样, 我们就通过Stroyboard搭建界面 (由于Demo代码较多, 只列举具体的动画部分)

我们首先先将动画抽象到一个类中:

class AnimatorFactory {
...
}

添加缩放动画:

static func scaleUp(view: UIView) -> UIViewPropertyAnimator {
let scale = UIViewPropertyAnimator(duration: 0.33, curve: .easeIn) //属性动画初始化
scale.addAnimations { //添加动画组
view.alpha = 1.0
}
scale.addAnimations({ //添加动画组
view.transform = .identity
}, delayFactor: 0.33) //延迟33%执行
scale.addCompletion {_ in //完成后打印
print("ready")
}
return scale
}

添加摇晃动画:

@discardableResult //去除黄色警告
static func jiggle(view: UIView) -> UIViewPropertyAnimator {
return UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.33, delay: 0, //直接执行属性动画
animations: { UIView.animateKeyframes(withDuration: 1, delay: 0, //关键帧动画
animations: { UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.25) {
view.transform = CGAffineTransform(rotationAngle: -.pi/8)
}
UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.75) {
view.transform = CGAffineTransform(rotationAngle: +.pi/8)
}
UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 1.0) {
view.transform = .identity
}
},
completion: nil
)
},
completion: {_ in
view.transform = .identity //完成后置空
}
)
}

添加淡入淡出动画:

@discardableResult
static func fade(view: UIView, visible: Bool) -> UIViewPropertyAnimator {
return UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.5, delay: 0.1,
options: [.curveEaseOut],
animations: {
view.alpha = visible ? 1 : 0
}
)
}

添加约束动画:

@discardableResult
static func animateConstraint(view: UIView, constraint: NSLayoutConstraint, by: CGFloat) -> UIViewPropertyAnimator {
let spring = UISpringTimingParameters(dampingRatio: 0.55) //这个和之前的弹簧动画类似
let animator = UIViewPropertyAnimator(duration: 1.0, timingParameters: spring)
animator.addAnimations {
constraint.constant += by //约束操作
view.layoutIfNeeded() //刷帧
}
return animator
}

添加闪烁动画:

static func grow(view: UIVisualEffectView, blurView: UIVisualEffectView) -> UIViewPropertyAnimator {
// 1
view.contentView.alpha = 0
view.transform = .identity // 2
let animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeIn) // 3
animator.addAnimations {
UIView.animateKeyframes(withDuration: 0.5, delay: 0.0, animations: { UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 1.0) {
blurView.effect = UIBlurEffect(style: .dark)
view.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
} UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) {
view.transform = view.transform.rotated(by: -.pi/8)
}
})
} // 4
animator.addCompletion {position in
switch position {
case .start:
blurView.effect = nil
case .end:
blurView.effect = UIBlurEffect(style: .dark)
default: break
}
}
return animator
}

进行属性动画的调用:

@IBAction func toggleShowMore(_ sender: UIButton) {

    self.showsMore = !self.showsMore

    let animations = { //创建动画组闭包
self.widgetHeight.constant = self.showsMore ? 230 : 130
if let tableView = self.tableView {
tableView.beginUpdates() //进行tableView刷新动画
tableView.endUpdates()
tableView.layoutIfNeeded() //刷布局
}
} let textTransition = { //View转场
UIView.transition(with: sender, duration: 0.25, options: .transitionCrossDissolve,
animations: {
sender.setTitle(self.showsMore ? "Show Less" : "Show More", for: .normal)
},
completion: nil
)
} if let toggleHeightAnimator = toggleHeightAnimator, toggleHeightAnimator.isRunning {
toggleHeightAnimator.addAnimations(animations)
toggleHeightAnimator.addAnimations(textTransition, delayFactor: 0.5)
} else {
let spring = UISpringTimingParameters(mass: 30, stiffness: 1000, damping: 300, initialVelocity: CGVector.zero)
toggleHeightAnimator = UIViewPropertyAnimator(duration: 0.0, timingParameters: spring) //初始化动画
toggleHeightAnimator?.addAnimations(animations) //添加动画组
toggleHeightAnimator?.addAnimations(textTransition, delayFactor: 0.5)
toggleHeightAnimator?.startAnimation() //开始动画
} widgetView.expanded = showsMore
widgetView.reload()
}

三、运行效果

1、运行效果

2、文件截图

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

[Animations] 快速上手 iOS10 属性动画的更多相关文章

  1. 如何快速上手基础的CSS3动画

    前言 说起CSS3动画,就必须说说 transform,translate,transition,animation这4个属性,transform主要定义元素的动作,比如旋转.倾斜.位移等,trans ...

  2. Netron开发快速上手(一):GraphControl,Shape,Connector和Connection

    版权所有,引用请注明出处:<<http://www.cnblogs.com/dragon/p/5203663.html >> 本文所用示例下载FlowChart.zip 一个用 ...

  3. 快速上手RaphaelJS-Instant RaphaelJS Starter翻译(一)

       (目前发现一些文章被盗用的情况,我们将在每篇文章前面添加原文地址,本文源地址:http://www.cnblogs.com/idealer3d/p/Instant_RaphaelJS_Start ...

  4. UnityShader快速上手指南(二)

    简介 前一篇介绍了如果编写最基本的shader,接下来本文将会简单的深入一下,我们先来看下效果吧 呃,gif效果不好,实际效果是很平滑的动态过渡 实现思路 1.首先我们要实现一个彩色方块 2.让色彩动 ...

  5. android104 帧动画,补间动画,属性动画

    ##帧动画FrameAnimation* 多张图片快速切换,形成动画效果* 帧动画使用xml定义 package com.itheima.frameanimation; import android. ...

  6. 快速上手最棒的网格框架ag-Grid

    由于对aggrid由衷的感谢, 又忍不住写了一篇软文来推广它(其实主要是为了弥补我把enterprise版扣下来后内心的愧疚...) ag-Grid是速度最快,功能最丰富的JavaScript dat ...

  7. 【转】Vue.js 2.0 快速上手精华梳理

    Vue.js 2.0 快速上手精华梳理 Sandy 发掘代码技巧:公众号:daimajiqiao 自从Vue2.0发布后,Vue就成了前端领域的热门话题,github也突破了三万的star,那么对于新 ...

  8. CSS快速入门基础篇,让你快速上手(附带代码案例)

    1.什么是CSS 学习思路 CSS是什么 怎么去用CSS(快速上手) CSS选择器(难点也是重点) 网页美化(文字,阴影,超链接,列表,渐变等) 盒子模型 浮动 定位 网页动画(特效效果) 项目格式: ...

  9. [Android开发学iOS系列] 快速上手UIKit

    快速上手iOS UIKit UIKit是苹果官方的framework, 其中包含了各种UI组件, window和view, 事件处理, 交互, 动画, 资源管理等基础设施支持. 按照前面的介绍, 用U ...

随机推荐

  1. .NET:CLR via C#:Runtime Serialization

    Making a Type Serializable The SerializableAttribute custom attribute may be applied to reference ty ...

  2. 在VirtualBox中为已有的磁盘增加磁盘大小

    ①打开CMD,进入到具体虚拟机镜像的存放位置. ②输入命令:VBoxManage modifyhd uuid --resize 25000,这里的25000单位是M,表示修改后的硬盘大小.若是VBox ...

  3. MyEclipse项目如何导入到Eclipse

    1.请首先确保你的eclipse是javaee版本的,或者已经安装看wtp插件 2.然后修改eclipse工程下的.project文件: 3.在<natures></natures& ...

  4. Cocos2d-x

    http://blog.csdn.net/ccf19881030/article/details/9204801 Cocos2d-x相关的博客以及官网信息 1.CSDN博主无幻的博客:http://b ...

  5. python文件目录操作

    一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法.1.得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()2.返回指定目录下的所有文件和目 ...

  6. JSON.parse()和JSON.stringify()方法

    parse用于从一个字符串中解析出json对象,如 var str = '{"name":"huangxiaojian","age":&qu ...

  7. [Android] repo 下载Android源码(国内镜像)

    reference : http://blog.csdn.net/shenlan18446744/article/details/51490560 repo 下载Android源码(国内镜像) 下载r ...

  8. LaTeX中的数学公式

    因为想在过年之前把论文写出来(虽然现在看来似乎痴人说梦),用word写PDE的公式简直是自己找虐,就想说自己研究一下LaTex,用起来发现这东西写格式性的文档真心甩word几个陈景润啊,出来的公式不仅 ...

  9. maven 将jar 下载到工程当前目录下

    在 pom.xml 的目录下,运行cmd命令 : call mvn -f pom.xml dependency:copy-dependencies 然后在同一目录下出现文件夹target,内容就是ja ...

  10. PL/SQL 下 Command window 与 SQL window 的区别

    1.Command window实现了SQL*Plus的所有功能,允许运行sql*plus命令,sql命令,sql脚本. 2.SQL window用于执行sql语句,显示sql输出,执行统计信息.(测 ...