因为这个问题提到了iOS 7,所以我很惊讶答案没有提到在iOS 7中引入的Animated Transitions API。
如果您想直接进入GitHub,那么objc.io的人有一个很棒的帖子,其中包含一个链接项目here
查看文档,您将看到以下内容:
@availability(iOS, introduced=7.0)
optional func navigationController(navigationController: UINavigationController,
animationControllerForOperation operation: UINavigationControllerOperation,
fromViewController fromVC: UIViewController,
toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
或者使用Objective-C
- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC NS_AVAILABLE_IOS(7_0);
这意味着从iOS 7开始,您可以控制导航控制器如何实现其推送和弹出动画。
您只需要设置导航控制器的委托并在适当时候返回正确的动画器对象即可。让我们开始吧:
1. 设置UINavigationControllerDelegate
通常我喜欢有一个全局的导航协调器来管理所有的转场等操作。因此,理想情况下,您希望有一个对象能够在NavigationController的整个生命周期内存在。因此,我们可能会有一个类似于以下内容的协调器:
class NavigationCoordinationController: NSObject {
private(set) var navigationController:UINavigationController
required init(navigationController: UINavigationController) {
self.navigationController = navigationController
super.init()
navigationController.delegate = self
}
}
通常我会在应用程序委托中创建它,以便可以在任何地方引用它。您还可以按视图控制器的要求设置委托,创建自定义的UINavigationController子类或将其设置在任何您认为合适的位置。
2. 创建自定义动画器
现在我们需要一个遵循UIViewControllerAnimatedTransitioning
协议的对象。每当需要进行动画转换时,都会调用此对象来应用动画。该示例是一个简单的动画,它会淡化并扩展过渡中的fromView,因此对于推送非常相关。
class CustomPushExpansionTransitioner: NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
return 1
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
let fromView: UIView = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
let toView: UIView = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
let container = transitionContext.containerView()
container.addSubview(toView)
container.bringSubviewToFront(fromView)
toView.frame = container.convertRect(fromView.bounds, fromView: fromView)
UIView.animateWithDuration(transitionDuration(transitionContext),
animations: { () -> Void in
fromView.alpha = 0
fromView.transform = CGAffineTransformConcat(fromView.transform, CGAffineTransformMakeScale(1.3, 1.3))
}) { (complete) -> Void in
transitionContext.completeTransition(true)
}
}
}
3. 在必要时出售动画师
现在我们需要实现UINavigationController代理,并在需要时出售我们的自定义动画师。
extension NavigationCoordinationController: UINavigationControllerDelegate {
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
switch operation {
case .Push:
return LaunchToHomeTransitioner()
case .Pop:
break
case .None:
break
}
return nil
}
}
现在您已经完全掌控了您的UINavigationController转换。
[self.view.window.layer addAnimation:transition forKey:nil];
而不是[self.view.layer addAnimation:transition forKey:nil];
- Pintouch