如果获取到了不是nil的对象,那么UIKit不会调用animator的animateTransition方法,而是调用交互式控制器(还记得前面介绍动画代理的示意图么,交互式动画控制器和animator是平级关系)的startInteractiveTransition:方法。
所谓的交互式动画,通常是基于手势驱动,产生一个动画完成的百分比来控制动画效果(文章开头的gif中第二个动画效果)。整个动画不再是一次性、连贯的完成,而是在任何时候都可以改变百分比甚至取消。这需要一个实现了UIPercentDrivenInteractiveTransition协议的交互式动画控制器和animator协同工作。这看上去是一个非常复杂的任务,但UIKit已经封装了足够多细节,我们只需要在交互式动画控制器和中定义一个时间处理函数(比如处理滑动手势),然后在接收到新的事件时,计算动画完成的百分比并且调用updateInteractiveTransition来更新动画进度即可。
用下面这段代码简单表示一下整个流程(删除了部分细节和注释,请不要以此为正确参考),完整的代码请参考demo中的Interactivity文件夹:
// 这个相当于fromViewController
class InteractivityFirstViewController: UIViewController {
// 这个相当于toViewController
lazy var interactivitySecondViewController: InteractivitySecondViewController = InteractivitySecondViewController()
// 定义了一个InteractivityTransitionDelegate类作为代理
lazy var customTransitionDelegate: InteractivityTransitionDelegate = InteractivityTransitionDelegate()
override func viewDidLoad() {
super.viewDidLoad()
setupView() // 主要是一些UI控件的布局,可以无视其实现细节
/// 设置动画代理,这个代理比较复杂,所以我们新建了一个代理对象而不是让self作为代理
interactivitySecondViewController.transitioningDelegate = customTransitionDelegate
}
// 触发手势时,也会调用animationButtonDidClicked方法
func interactiveTransitionRecognizerAction(sender: UIScreenEdgePanGestureRecognizer) {
if sender.state == .Began {
self.animationButtonDidClicked(sender)
}
}
func animationButtonDidClicked(sender: AnyObject) {
self.presentViewController(interactivitySecondViewController, animated: true, completion: nil)
}
}
非交互式的动画代理只需要为present和dismiss提供animator即可,但是在交互式的动画代理中,还需要为present和dismiss提供交互式动画控制器:
class InteractivityTransitionDelegate: NSObject, UIViewControllerTransitioningDelegate {
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return InteractivityTransitionAnimator(targetEdge: targetEdge)
}
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return InteractivityTransitionAnimator(targetEdge: targetEdge)
}
/// 前两个函数和淡入淡出demo中的实现一致
/// 后两个函数用于实现交互式动画
func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return TransitionInteractionController(gestureRecognizer: gestureRecognizer, edgeForDragging: targetEdge)
}
func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return TransitionInteractionController(gestureRecognizer: gestureRecognizer, edgeForDragging: targetEdge)
}
}










