液体过渡提供了新的 API 以创建过渡。
功能
- 易于使用且便捷的 API(更少的模板代码)
- 向后动画
- 在任何时候中断过渡以进行交互
- 用于恢复视图状态的辅助类
- 自定义属性动画 (或
CALayer
属性) - 没有 '延迟' 的复杂过渡
在您的 Podfile 中添加以下条目
pod 'LiquidTransition'
然后运行 pod install
。
记得在您想使用 LiquidTransition 的每个文件中导入 import LiquidTransition
。
使用方法
像这样,您可以创建简单的过渡动画。
import LiquidTransition
class FadeTransition: Animator<FromViewController, ToViewController> {
init() {
super.init()
duration = 0.3
timing = Timing.default
// do not perform here complex operations, cause it calls on app initialization
}
override func animation(src: FromViewController, dst: ToViewController, container: UIView, duration: Double) {
dst.view.alpha = 0
// perform linear animation and manage timing function with `self.timing`
UIView.animate(withDuration: duration, delay: 0, options: [.curveLinear], animations: {
dst.view.alpha = 1
}) { _ in
dst.view.alpha = 1 // if anim somehow canceled
}
}
}
应用程序启动时,您可以设置过渡动画。
Liquid.shared.becomeDelegate() // Liquid automaticly becomes delegates for all animated transitions
Liquid.shared.addTransitions([FadeTransition()])
这就完了!简单到难以置信?! :)
自定义
import LiquidTransition
class ExampleTransition: Animator<SampleController, CardsNavigationController> {
var imgView: UIImageView!
override init() {
super.init()
duration = 0.4
timing = Timing.init(closure: { $0 * $0 })
addCustomAnimation {[weak self] (progress) in
self?.imgView?.layer.cornerRadius = 20 * (1-progress)
}
}
override func animation(src: SampleController, dst: CardsNavigationController, container: UIView, duration: Double) {
imgView = dst.imgView
// this class restore all views state before transition
// when you have lot of property changes, it can be might helpfull
let restore = TransitionRestorer()
restore.addRestore(imgView, src.fadeView)
// cause on end transition we dont want restore superview of `src.view` and `dst.view`
restore.addRestore(dst.view, ignoreFields: [.superview])
dst.view.alpha = 0
UIView.animate(withDuration: duration, delay: 0, options: [.curveLinear], animations: {
dst.view.alpha = 1
src.fadeView.alpha = 0
self.imgView.frame = CGRect(/*new frame*/)
}) { _ in
restore.restore()
}
}
}
有时我们需要一个过渡动画适用于多个控制器。在这种情况下,您可以定义UIViewController
作为模板类,并通过多个类来调用初始化方法。
class FadeTransition: Animator<UIViewController, UIViewController> {
init() {
super.init(from: [VC1.self, VC2.self, VC3.self], to: [VC4.self, VC5.self], direction: .both)
duration = 0.3
}
override func animation(src: UIViewController, dst: UIViewController, container: UIView, duration: Double) {
// animation
}
或者使用协议,以访问公共视图。如果不是这种情况,您可以重写canAnimate
函数。
open func canAnimate(src: UIViewController, dst: UIViewController, direction animDirection: Direction) -> Bool
并定义您的条件
待办事项
- 逆向动画
- 自定义的时间函数
- 允许自定义动画
- 恢复视图状态帮助类
- 为复杂准备动画提供平滑的交互式动画
- 支持Cocoapods
- 支持Swift包管理器
- 支持Carthage
- 为
TransitionRestorer
添加自定义保存密钥 - 添加一些默认动画
说明
LiquidTransition控制动画百分比完成。因此,如果在一个方向上定义了动画,它可以运行反向动画。在反向动画中,从1到0运行。因此,如果您与NSNavigationController
一起使用带navigationBar
,则可以看到navigationBar
是反向动画的(参见具有照片的示例)。在这种情况下,最好在两个方向上定义动画。
LiquidTransition“受Hero
启发。在我们具有自定义动画的复杂UI中。数周前我们试图在Hero
中实现性能动画。当Hero
没什么作用时,我们检查了手动实现过渡。它更快。因为Hero
进行了许多快照,执行过渡变得停滞。在真实项目中,Hero
显示性能不足,并且需要大量代码来表达您真正想要的。因此,在真实应用程序中,手动过渡看起来更合适。Hero
已从项目中移除,我们转向手动控制的过渡。新库的一些部分开始出现在我们的项目中。现在一些想法和代码已被移转并重构为通用库中的使用。
如果您在寻找类似的东西,请查看Transition和EasyTransitions。在这完成LiquidTransition
之后,我发现这两个项目有很好的点子。它们可能不够方便,但仍然是很好的库。
致谢
亚历山大·格拉申科夫:[email protected]
iOS
和 计算机视觉
开发者