最近在学swift,就用swift写了个小Demo[https://github.com/jiaowoxiaoming/CustomNavigaitonAnimations ]。
在项目中常常看见别的App不是用的原生的Push/Pop动画,都是怎么做的呢。iOS7之后,苹果就为我们做好接口了,让我们能灵活的控制UIViewController的切换。
言归正传,从零开始做一个转场动画。
从创建自定义Push/Pop说起
首先创建工程,storyBoard中拖一个ViewController,给它加上导航控制器。完毕之后,需要考虑动画的实现方式,恩,用transform动画吧。很简单的放大缩小动画。
因为我们需要自定义动画,所以需要实现UINavigationControllerDelegate
协议方法。具体方法如下:
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
//这里用到了一个属性来记录当前操作的类型(Push or Pop)
navigationOperation = operation
return self
}
在这里再赘述一下UINavigationControllerDelegate
其他协议方法(已经了解的当我没说)
//这个方法就是切换横竖屏时调用的操作 设置方法设置导航控制器支持的设备方向
@available(iOS 7.0, *)
optional public func navigationControllerSupportedInterfaceOrientations(navigationController: UINavigationController) -> UIInterfaceOrientationMask
//这个方法设置导航控制器的首选设备方向
@available(iOS 7.0, *)
optional public func navigationControllerPreferredInterfaceOrientationForPresentation(navigationController: UINavigationController) -> UIInterfaceOrientation
//下面两个方法可以对导航的转场动画进行设置 1.交互式动画 2.传统的push/pop 动画
@available(iOS 7.0, *)
optional public func navigationController(navigationController: UINavigationController, interactionControllerForAnimationController animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?
@available(iOS 7.0, *)
optional public func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
然后控制器需要实现另外一个协议UIViewControllerAnimatedTransitioning
它有三个方法:
// 动画时间
public func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval
// 具体动画操作
public func animateTransition(transitionContext: UIViewControllerContextTransitioning)
//动画结束的回调方法
optional public func animationEnded(transitionCompleted: Bool)
需要实现animateTransition
和transitionDuration
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView()
let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
let fromeViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
var destView:UIView!
var destTransform:CGAffineTransform!
if navigationOperation == UINavigationControllerOperation.Push {
containerView?.insertSubview((toViewController?.view)!, aboveSubview: (fromeViewController?.view)!)
destView = toViewController?.view
destView.transform = CGAffineTransformMakeScale(0.1, 0.1)
destTransform = CGAffineTransformMakeScale(1, 1)
}
else if navigationOperation == UINavigationControllerOperation.Pop
{
containerView?.insertSubview((toViewController?.view)!, belowSubview: (fromeViewController?.view)!)
destView = fromeViewController?.view
destTransform = CGAffineTransformMakeScale(0.1, 0.1)
}
UIView .animateWithDuration(transitionDuration(transitionContext), animations: {
destView.transform = destTransform!
}, completion: ({completed in
transitionContext.completeTransition(true)
}))
}
到此一个自定义的导航转场动画就完成了,至于具体的动画,在此我只是抛砖引玉,大家完全可以写出更绚丽的动画。