进展
一个用于iOS、tvOS和macOS的动画库,它使用基于物理的动画(包括弹簧)来提供真实感动的交互。
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
// Springs animate changes to a value
let spring = Spring(initialValue: view.center)
// The `onChange` closure will be called every time the spring updates
spring.onChange = { [view] newCenter in
view.center = newCenter
}
/// The view's center will realistically animate to the new target value.
spring.target = CGPoint(x: 300, y: 200)
安装
有几个方法可以将进展集成到项目中。
-
手动:将
Advance.xcodeproj
添加到您的项目中,然后将Advance-{iOS|macOS|tvOS}.framework
添加为“嵌入式二进制”到您的应用程序目标(在目标设置中的“常规”下)。然后添加import Advance
到您的代码中,您就完成了。 -
Carthage:将
github "timdonnelly/Advance"
添加到您的Cartfile
中。 -
CocoaPods:将
pod 'Advance'
添加到您的Podfile
中。 -
Swift Package Manager:在您的
Project.swift
中添加一个依赖项:.package(url: "http://github.com/timdonnelly/Advance", from: "3.0.0")
要求
- iOS 10+、tvOS 10+或macOS 10.12+
- Swift 5.0(Xcode 10.2或更高版本)
使用
API 文档在此 可用。
高级动画应用于每一帧(在iOS/tvOS上使用 CADisplayLink
,在macOS上使用 CVDisplayLink
),允许在任何时候进行精细控制。
Spring
Spring
实例通过使用弹簧物理动画一个值在时间上的变化。
let spring = Spring(initialValue: 0.0)
spring.onChange = { [view] newAlpha in
view.alpha = newAlpha
}
// Off it goes!
spring.target = 0.5
配置一个弹簧
/// Spring values can be adjusted at any time.
spring.tension = 30.0 /// The strength of the spring
spring.damping = 2.0 /// The resistance (drag) that the spring encounters
spring.threshold = 0.1 /// The maximum delta between the current value and the spring's target (for each component) for which the simulation can enter a converged state.
/// Update the simulation state at any time.
spring.velocity = 6.5
spring.value = 0.2
/// Sets the spring's target and the current simulation value, and removes all velocity. This causes the spring to converge at the given value.
spring.reset(to: 0.5)
Animator
Animator
提供了更大的灵活性来进行动画,但这牺牲了一部分便利性。具体来说,动画器允许对单一值执行任何类型的动画或模拟。
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
/// Animators coordinate animations to drive changes to a value.
let sizeAnimator = Animator(initialValue: view.bounds.size)
sizeAnimator.onChange = { [view] newSize in
view.bounds.size = newSize
}
/// A simple timed animation
sizeAnimator.animate(to: CGSize(width: 123, height: 456), duration: 0.25, timingFunction: .easeInOut)
/// Some time in the future (before the previous timed animation was complete)...
/// Spring physics will move the view's size to the new value, maintaining the velocity from the timed animation.
sizeAnimator.simulate(using: SpringFunction(target: CGSize(width: 300, height: 300)))
/// Some time in the future (before the previous spring animation was complete)...
/// The value will keep the same velocity that it had from the preceeding spring
/// animation, and a decay function will slowly bring movement to a stop.
sizeAnimator.simulate(using: DecayFunction(drag: 2.0))
动画器支持两种基本不同的动画类型:按时间动项目和模拟动画。
时间动画
时间动画是有时间限制的:它们有一个固定的持续时间,并以可预测的方式将动画转换为最终值。
animator.animate(to: CGSize(width: 123, height: 456), duration: 0.25, timingFunction: .easeInOut)
TimingFunction
描述了时间动画的速度。
TimingFunction
附带了一系列标准函数
TimingFunction.linear // No easing
TimingFunction.easeIn
TimingFunction.easeOut
TimingFunction.easeInOut
TimingFunction.swiftOut // Similar to Material Design's default curve
自定义时间函数可以表示为单元贝兹尔曲线 (在这里描述).
let customTimingFunction = TimingFunction(x1: 0.1, y1: 0.2, x2: 0.6, y2: 0.0)
模拟动画
模拟动画使用一个 模拟函数 驱动基于物理的过渡。模拟函数是符合 SimulationFunction
协议的类型。
可以使用两种不同的方法启动模拟动画
// Begins animating with the custom simulation function, maintaining the previous velocity of the animator.
animator.simulate(using: MyCustomFunction())
// or...
// Begins animating with the custom simulation function, imparting the specified velocity into the simulation.
animator.simulate(using: DecayFunction(), initialVelocity: dragGestureRecognizer.velocity(in: view))
自定义类型的动画
符合 VectorConvertible
协议的值可以通过 Advance 进行动画处理。符合的类型的可转为 Vector
的实现,反之亦然。
public protocol VectorConvertible: Equatable, Interpolatable {
associatedtype VectorType: SIMD where VectorType.Scalar == Double
init(vector: VectorType)
var vector: VectorType { get }
}
库通过扩展添加了对许多常见类型的支持。
参与贡献
如果您遇到任何问题或意外,请提交一个 issue。
对于建议或新功能,请考虑添加一个带有功能实现的 PR。如果您不确定如何实现更改,可以考虑提交一个 issue,但工作代码通常更容易评估。
许可
本项目采用 BSD 2-clause 许可协议 发布。