我希望有一个奇怪的UINavigationController
概念,您可以通过平移(如iOS 7流行手势)将视图控制器从堆栈中弹出,但它会记住弹出的视图控制器,允许你通过平移另一个方向来“取消它”(将其推回到堆栈上)。可以把它想象成Safari中的前进和后退按钮,如果你想回去,你仍然可以继续前进,然后把页面带回来。
我已经将UINavigationController
子类化,并将自己设置为委托,返回UIViewControllerAnimatedTransitioning
对象和UIPercentDrivenInteractiveTransition
对象:
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if operation == .Push {
return Animator(presenting: true)
} else if operation == .Pop {
return Animator(presenting: false)
} else {
return nil
}
}
和
func navigationController(navigationController: UINavigationController, interactionControllerForAnimationController animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
if animationController is Animator {
return interactiveTransition
} else {
return nil
}
}
根据Animator是否设置呈现,我会调用特定的方法,如果呈现的是真的:
func presentWithTransitionContext(transitionContext: UIViewControllerContextTransitioning) {
let toViewControllerView = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!.view
let containerView = transitionContext.containerView()
containerView.addSubview(toViewControllerView)
toViewControllerView.transform = CGAffineTransformMakeTranslation(containerView.bounds.width, 0.0)
applyShadowToView(toViewControllerView)
let animationCurve: UIViewAnimationOptions = transitionContext.isInteractive() ? .CurveLinear : .CurveEaseInOut
UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, options: animationCurve, animations: {
toViewControllerView.transform = CGAffineTransformIdentity
}, completion: { finished in
return transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
})
}
我覆盖popViewControllerAnimated
,因此我可以保存正在弹出的视图控制器:
override func popViewControllerAnimated(animated: Bool) -> UIViewController? {
poppedViewControllers.insert(visibleViewController!, atIndex: 0)
return super.popViewControllerAnimated(animated)
}
我在UIPanGestureRecognizer
子类'UINavigationController
中添加awakeFromNib()
到它的视图,并调用此方法来推送/弹出:
func panned(panGestureRecognizer: UIPanGestureRecognizer) {
let panningRight = panGestureRecognizer.translationInView(view).x > 0
let progress: CGFloat
if panningRight {
progress = panGestureRecognizer.translationInView(view).x / view.bounds.width
} else {
progress = -panGestureRecognizer.translationInView(view).x / view.bounds.width
}
if panGestureRecognizer.state == .Began {
interactiveTransition = UIPercentDrivenInteractiveTransition()
if panningRight {
popViewControllerAnimated(true)
} else {
let viewControllerToPush = poppedViewControllers[0]
poppedViewControllers.removeAtIndex(0)
pushViewController(viewControllerToPush, animated: true)
}
} else if panGestureRecognizer.state == .Changed {
interactiveTransition!.updateInteractiveTransition(progress)
} else if panGestureRecognizer.state == .Ended {
if progress > 0.5 {
interactiveTransition!.finishInteractiveTransition()
} else {
interactiveTransition!.cancelInteractiveTransition()
}
interactiveTransition = nil
} else if panGestureRecognizer.state == .Cancelled {
interactiveTransition!.cancelInteractiveTransition()
interactiveTransition = nil
}
}
然而,每当我手势将先前弹出的视图控制器推到导航堆栈上时,它就会以相反的方式为演示文稿设置动画(显示的视图控制器立即显示,并且当前视图控制器滑开)。我不知道为什么会这样。两种情况都不可能吗?我不应该删除视图吗?