需求分析:
产品经理:我们的App页面切换时能不能不要总从右边把页面推出来啊
程序员:这个需要自定义转场动画...
产品经理:这个自定义转场难不难,不难就改改吧!
程序员:...
自定义转场动画实现逻辑
从iOS7开始,我们可以自定义转场动画了。转场动画主要还是分为两种:push和model,下面分别介绍实现方法。
自定义push转场动画
步骤:(以vc1 push到vc2为例)
- 在vc1里需要实现UINavigationControllerDelegate的代理方法,该方法返回自定义动画对象就行了
- 直接调用push方法就行了
- 自定义动画实现(这个好像才是第一步)
直接贴代码了:
// 1. 在vc1里需要实现UINavigationControllerDelegate的代理方法
class VC1: UIViewController, UINavigationControllerDelegate
// 自定义的push动画,后面介绍实现
var pushAnimation = CustomAnimation()
// MARK: - event response
@IBAction func presentBtnClicked(_ sender: Any) {
// 2. 直接调用push方法就行了,记得设置UINavigationControllerDelegate
let vc = UIViewController()
vc.view.backgroundColor = UIColor.lightGray
navigationController?.delegate = self // 必须设置
navigationController?.pushViewController(vc, animated: true)
}
// MARK: - UINavigationControllerDelegate
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return pushAnimation
}
自定义动画类:
// 自定义动画类需要遵循UIViewControllerAnimatedTransitioning协议
class CustomAnimation: NSObject, UIViewControllerAnimatedTransitioning {
// 返回动画持续时间
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.8
}
// 动画实现逻辑
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
// 1. 从transitionContext获取目标视图控制器toVC
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
// 2. 设置toVC的初始位置和最终位置
let screenBounds = UIScreen.main.bounds
let finalFrame = transitionContext.finalFrame(for: toVC!)
toVC!.view.frame = screenBounds.offsetBy(dx: -screenBounds.size.width, dy: 0)
// 3. 添加VC的view到containerView上
let containerView = transitionContext.containerView
containerView.addSubview(toVC!.view)
// 4. 开始动画,下面调用了iOS7新加的一个弹性动画
let duaration = transitionDuration(using: transitionContext)
UIView.animate(withDuration: duaration,
delay: 0,
usingSpringWithDamping: 0.6,
initialSpringVelocity: 0,
options: UIViewAnimationOptions.curveLinear,
animations: {
toVC!.view.frame = finalFrame
}) { (_) in
transitionContext.completeTransition(true)
}
}
}
自定义Model动画(present)
步骤:(以vc1 present到vc2为例)
- vc1实现转场协议UIViewControllerTransitioningDelegate
- 调用系统的present方法跳转即可
代码:
// vc1需要遵循转场协议UIViewControllerTransitioningDelegate
class VC1: UIViewController, UIViewControllerTransitioningDelegate {
// 自定义转场动画,这里还使用上面的自定义动画
var presentAnimation = CustomAnimation()
// MARK: - event response
@IBAction func presentBtnClicked(_ sender: Any) {
// 2. 调用系统的present方法跳转
let vc = UIViewController()
vc.view.backgroundColor = UIColor.lightGray
vc.transitioningDelegate = self
present(vc, animated: true, completion: nil)
}
// 1. vc1实现转场协议的方法
// MARK: - UIViewControllerTransitioningDelegate
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return presentAnimation
}