Reputation: 622
I am trying to set an interactive transition with this class :
class TransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerInteractiveTransitioning, UIViewControllerTransitioningDelegate, UIViewControllerContextTransitioning {
weak var transitionContext: UIViewControllerContextTransitioning?
var sourceViewController: UIViewController! {
didSet {
enterPanGesture = UIScreenEdgePanGestureRecognizer()
enterPanGesture.addTarget(self, action:"panned:")
enterPanGesture.edges = UIRectEdge.Left
sourceViewController.view.addGestureRecognizer(enterPanGesture)
}
}
var togoSourceViewController: UIViewController!
let duration = 1.0
var presenting = true
var reverse = false
var originFrame = CGRectNull
var shouldBeInteractive = false
private var didStartedTransition = false
private var animated = false
private var interactive = false
private var AnimationStyle = UIModalPresentationStyle(rawValue: 1)
private var didFinishedTransition = false
private var percentTransition: CGFloat = 0.0
private var enterPanGesture: UIScreenEdgePanGestureRecognizer!
private var tovc = UIViewController()
private var pointtovc = CGPoint()
private var pointfromvc = CGPoint()
private var fromvc = UIViewController()
private var generalcontainer = UIView()
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
animated = true
let container = transitionContext.containerView()
let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
if reverse {
toViewController.view.center.x -= (container?.bounds.size.width)!
container?.insertSubview(toViewController.view, aboveSubview: fromViewController.view)
} else {
toViewController.view.center.x += (container?.bounds.size.width)!
container?.addSubview(toViewController.view)
}
UIView.animateWithDuration(duration, delay: 0.0, options: UIViewAnimationOptions.TransitionNone, animations: {
if self.reverse {
toViewController.view.center.x += (container?.bounds.size.width)!
} else {
toViewController.view.center.x -= (container?.bounds.size.width)!
}
}, completion: { finished in
transitionContext.completeTransition(true)
self.animated = false
self.reverse = !self.reverse
})
}
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return duration
}
func startInteractiveTransition(transitionContext: UIViewControllerContextTransitioning) {
interactive = true
animated = true
let container = transitionContext.containerView()
let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)! //ArticleView
let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)! //Article OU Favoris
if reverse {
toViewController.view.frame.origin.x = -fromViewController.view.frame.maxX
container?.insertSubview(toViewController.view, aboveSubview: fromViewController.view)
}
tovc = toViewController
pointtovc = toViewController.view.bounds.origin
fromvc = fromViewController
pointfromvc = fromViewController.view.bounds.origin
generalcontainer = container!
}
func containerView() -> UIView? {
return sourceViewController?.view
}
func viewControllerForKey(key: String) -> UIViewController? {
return sourceViewController?.storyboard!.instantiateViewControllerWithIdentifier(key)
}
func viewForKey(key: String) -> UIView? {
return sourceViewController?.storyboard!.instantiateViewControllerWithIdentifier(key).view
}
func initialFrameForViewController(vc: UIViewController) -> CGRect {
return vc.view.frame
}
func finalFrameForViewController(vc: UIViewController) -> CGRect {
return vc.view.frame
}
func isAnimated() -> Bool {
return animated
}
func isInteractive() -> Bool {
return interactive
}
func presentationStyle() -> UIModalPresentationStyle {
return AnimationStyle!
}
func completeTransition(didComplete: Bool) {
interactive = false
animated = false
shouldBeInteractive = false
didFinishedTransition = didComplete
transitionContext?.finishInteractiveTransition()
transitionContext?.completeTransition(true)
}
func updateInteractiveTransition(percentComplete: CGFloat) {
if self.reverse {
print(percentComplete)
self.tovc.view.frame.origin.x = (self.fromvc.view.frame.maxX * (percentComplete)) - self.fromvc.view.frame.maxX
}
}
func finishInteractiveTransition() {
UIView.animateWithDuration(duration, delay: 0.0, options: UIViewAnimationOptions.TransitionNone, animations: {
if self.reverse {
self.tovc.view.frame.origin.x = self.fromvc.view.frame.origin.x
}
}, completion: { finished in
self.animated = false
self.reverse = !self.reverse
self.completeTransition(true)
})
}
func cancelInteractiveTransition() {
UIView.animateWithDuration(duration, delay: 0.0, options: UIViewAnimationOptions.TransitionNone, animations: {
if self.reverse {
self.tovc.view.frame.origin.x = -self.fromvc.view.frame.maxX
}
}, completion: { finished in
self.animated = false
self.completeTransition(true)
})
}
func transitionWasCancelled() -> Bool {
return didFinishedTransition
}
func targetTransform() -> CGAffineTransform {
return CGAffineTransform()
}
func completionSpeed() -> CGFloat {
return 1 - percentTransition
}
func panned(pan: UIPanGestureRecognizer) {
switch pan.state {
case .Began:
animated = true
shouldBeInteractive = true
didStartedTransition = true
didFinishedTransition = false
sourceViewController?.dismissViewControllerAnimated(true, completion: nil)
updateInteractiveTransition(0)
break
case .Changed:
percentTransition = CGFloat(pan.translationInView(sourceViewController!.view).x / sourceViewController!.view.frame.width)
if percentTransition < 0.0 {
percentTransition = 0.0
} else if percentTransition > 1.0 {
percentTransition = 1.0
}
updateInteractiveTransition(percentTransition)
break
case .Ended, .Failed, .Cancelled:
animated = false
shouldBeInteractive = false
didStartedTransition = false
didFinishedTransition = true
if percentTransition < 0.8 {
cancelInteractiveTransition()
} else {
finishInteractiveTransition()
}
break
case .Possible:
break
}
}
}
The animateTransition
works perfectly and dismiss my fromViewController but during my InteractiveTransition
when I call finishInteractiveTransition()
and then completeTransition(true)
, I still have my both view :
But on Apple they said :
You must call this method after your animations have completed to notify the system that the transition animation is done. The parameter you pass must indicate whether the animations completed successfully. For interactive animations, you must call this method in addition to the finishInteractiveTransition or cancelInteractiveTransition method. The best place to call this method is in the completion block of your animations.
So, what am I doing wrong ?
I am using ios9, swift 2, Xcode 7 beta 6
Upvotes: 0
Views: 625
Reputation: 622
I found the solution :
i should call transitionContext.completeTransition(true)
in function finishInteractiveTransition()
but on my previous code transitionContext
was not the same that in startInteractiveTransition(transitionContext: UIViewControllerContextTransitioning)
So i add one variable :
private var Context: UIViewControllerContextTransitioning?
and use this to call :
transitionContext.completeTransition(true)
or
transitionContext.completeTransition(false)
Upvotes: 1