Theoretical question : in the code below, why, at the line of "performSegue....", the segue is not performed entirely ? I mean, how it know it's an interactive transition, and why the method "performSegue..." has not the same effect as if she was declared somewhere else ?
let transitionManager = TransitionManager()
override func viewDidLoad() {
super.viewDidLoad()
transitionManager.sourceViewController = self
// Do any additional setup after loading the view.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
let dest = segue.destinationViewController as UIViewController
dest.transitioningDelegate = transitionManager
transitionManager.destViewController = dest
}
The segue is from the FirstViewController to the SecondViewController.
Identifier : "segueIdentifier"
Segue : Modal
Destination : Current
class TransitionManager: UIPercentDrivenInteractiveTransition,UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate,UIViewControllerInteractiveTransitioning {
var interactive = false
var presenting = false
var panGesture : UIPanGestureRecognizer!
var sourceViewController : UIViewController! {
didSet {
panGesture = UIPanGestureRecognizer(target: self, action: "gestureHandler:")
sourceViewController.view.addGestureRecognizer(panGesture)
}
}
func gestureHandler(pan : UIPanGestureRecognizer) {
let translation = pan.translationInView(pan.view!)
let d = translation.x / pan.view!.bounds.width * 0.5
switch pan.state {
case UIGestureRecognizerState.Began :
interactive = true
sourceViewController.performSegueWithIdentifier("segueIdentifier", sender: self)
case UIGestureRecognizerState.Changed :
self.updateInteractiveTransition(d)
default :
interactive = false
if d > 0.2 || velocity.x > 0 {
self.finishInteractiveTransition()
}
else {
self.cancelInteractiveTransition()
}
}
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
//Something....
UIView.animateWithDuration(1.0, animations: {
//Something....
}, completion: {}
})
}
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
return 1
}
// MARK: UIViewControllerTransitioningDelegate protocol methods
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.presenting = true
return self
}
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.presenting = false
return self
}
func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return self.interactive ? self : nil
}
func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return self.interactive ? self : nil
}
}
In fact, I have a lot of codes similar to this, this one is working but others very similar do precisely what I was explaining : the segue is just executed without interactive transition. Can someone explain me ?
Thanks for your help
If the problem is that your interactive transition animation is not being interactive, I'd suggest putting a breakpoint in interactionControllerForPresentation
:
Make sure that the correct instance of interactionControllerForPresentation
is called like you think it should be.
For example, make sure that viewDidLoad
of destination didn't replace the transitioningDelegate
that you so carefully set in the prepareForSegue
in the source controller ... this is easy to do if doing interactive transition from A to B and then again from B to C, what you set up in anticipation to B to C can interfere with what you intended to do from A to B.
Make sure that interactionControllerForPresentation
is returning the value that you think it should (i.e. make sure that interactive
is definitely true
).
Every time I've seen this behavior of a gesture not initiating the transition interactively, like I think it should, it has been because when interactionControllerForPresentation
was called in the destination controller's transitioningDelegate
, it didn't return a valid UIViewControllerInteractiveTransitioning
(such as a UIPercentDrivenInteractiveTransition
) like I intended it to.
Anyway, you can diagnose this by adding a log statement in interactionControllerForPresentation
, and you'll either see that (a) it's not called for some reason; or (b) self.interactive
is not true
.