Reputation: 163
I've been trying to make UINavigationViewControllerDelegate
to implement the required methods for custom transitions. They are working as expected and I am also able to add interactive transitions into the mix as well.
The problem is that when I implement those methods I lose the default "swipe right to go back" support from normal navigation transitions completely. I gain those back by setting the navigationController.delegate = nil
before entering the view controllers I want to have the normal transitions. This means I'll have to store the actual old delegate and re-set it when I return from the view.
The documentation states that one should return nil
from the navigationController:interactionControllerForAnimationController:
and navigationController:animationControllerForOperation:fromViewController:toViewController:
which is exactly what I am doing:
- (id<UIViewControllerAnimatedTransitioning>)navigationController:
(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
if([fromVC isKindOfClass:[MainViewController class]] &&
[toVC isKindOfClass:[MenuViewController class]]) {
self.menuTransition.isPresentation = YES;
return self.menuTransition;
} else if([toVC isKindOfClass:[MainViewController class]] &&
[fromVC isKindOfClass:[MenuViewController class]]){
self.menuTransition.isPresentation = NO;
return self.menuTransition;
}
return nil;
}
- (id<UIViewControllerInteractiveTransitioning>) navigationController
(UINavigationController *)navigationController
interactionControllerForAnimationController:
(id<UIViewControllerAnimatedTransitioning>)animationController
{
MenuTransition *t = (MenuTransition*)animationController;
if(![t isPresentation] && [t isInteractive]) {
return self.menuTransition;
}
return nil;
}
What else could be wrong here?
Upvotes: 0
Views: 562
Reputation: 1153
When push viewController2 in viewController1 set navigationController.delegate = nil
, then in your pushed view controller interactive pop gesture will be default and work perfectly, and when you pop viewController2
add this code to viewController1
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.delegate = navigationController as? UINavigationControllerDelegate
}
Upvotes: 0
Reputation: 1236
The docs do give the impression that returning nil would work, but I found that the gesture recognizers were conflicting. Implementing gestureRecognizerShouldBegin fixed the issue for me.
*Note, this was written in swift but should be easy enough to convert to obj-c. This is a Navigation Controller SubClass with the UIGestureRecognizerDelegate Protocol
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.interactivePopGestureRecognizer.delegate = self
self.transitionGesture = UIPanGestureRecognizer(target: self, action: "handlePanGesture:")
self.view.addGestureRecognizer(transitionGesture)
self.transitionGesture!.delegate = self
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer!) -> Bool {
if self.transitionCoordinator()?.isAnimated() {
return false
}
if self.viewControllers.count < 2 {
return false
}
var currentVC: UIViewController? = self.viewControllers[self.viewControllers.count-1] as? UIViewController
if let vc = currentVC as? MyCustomVC {
if gestureRecognizer == self.transitionGesture {
return true
}
} else if gestureRecognizer == self.interactivePopGestureRecognizer {
return true
}
return false
}
Upvotes: 2