Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TabBarController with interactive animated transitioning

I'm trying to implement interactive animated transition between tabs in a TabBar. I'm using a pan gesture recogniser. I made a custom animation and use UIPercentDrivenInteractiveTransition to make the switching interactive. But it seems that I don't really understand the process that goes behind all the animation.
I did manage to make a non-interactive animation, but adding interactivity was somehow difficult. I read many tutorials on the internet and I fully understand how the code snippets that everybody posts works but I somehow can't implement it in my case. I made a TabBar application with 2 tabs both with navigation bar.
Here is my code:

TabBarController.swift

import UIKit

class TabBarController: UITabBarController, UITabBarControllerDelegate {

var usingGesture = false
var interactiveTransition:UIPercentDrivenInteractiveTransition?

override func viewDidLoad() {
    super.viewDidLoad()
    let panGesture = UIPanGestureRecognizer(target: self, action: "didPan:")
    self.view.addGestureRecognizer(panGesture)
    self.delegate = self
    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func tabBarController(tabBarController: UITabBarController, interactionControllerForAnimationController animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
    return self.interactiveTransition
}

func didPan(gesture: UIPanGestureRecognizer){
    let point = gesture.locationInView(gesture.view)
    let percent = fmax(fmin((point.x / 300.0), 0.99), 0.0)
    self.interactiveTransition = UIPercentDrivenInteractiveTransition()

    switch (gesture.state){
    case .Began:
        self.usingGesture = true
        self.selectedIndex++
    case .Changed:
        self.interactiveTransition?.updateInteractiveTransition(percent)
    case .Ended, .Cancelled:
        if percent > 0.5 {
            self.interactiveTransition?.finishInteractiveTransition()
        } else {
            self.interactiveTransition?.cancelInteractiveTransition()
        }
        self.usingGesture = false
    default:
        NSLog("Unhandled state")
    }
}
}

TransitionToLeft.swift

import UIKit

class TransitionToLeft: UIPercentDrivenInteractiveTransition, UIViewControllerAnimatedTransitioning {

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

    let fromView:UIView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
    let toView:UIView = transitionContext.viewForKey(UITransitionContextToViewKey)!

    transitionContext.containerView().addSubview(fromView)
    transitionContext.containerView().addSubview(toView)

    toView.frame = CGRectMake(toView.frame.width, 0, toView.frame.width, toView.frame.height)
    let fromNewFrame = CGRectMake(-1 * fromView.frame.width, 0, fromView.frame.width, fromView.frame.height)

    UIView.animateWithDuration( 0.7, animations:{ () -> Void in
        toView.frame = fromView.frame
        fromView.frame = fromNewFrame
        },{ (Bool) -> Void in
            // update internal view - must always be called
            transitionContext.completeTransition(true)
    })

}
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
    return 0.7
}

}

Can someone help me figure this out?

like image 927
Amer Hukic Avatar asked Nov 10 '22 20:11

Amer Hukic


1 Answers

I think your problem is in gesture recognizer. Try to add it to self.selectedViewController.view instead of self.view.

Also, your code is wrong: self.interactiveTransition = UIPercentDrivenInteractiveTransition() should be self.interactiveTransition = TransitionToLeft() I think.

like image 132
silvansky Avatar answered Nov 25 '22 06:11

silvansky