Search code examples
swiftanimationuitabbarcontrollerselectedindex

View transitions when TabBatController.selectedIndex changed programmatically


I have some troubles to get the views transitions animated when I change the UITabBarController.selectedIndex changed programmatically.

When I tap on a TabBar icon the animation works fine, but when I change the selectedIndex from a gestureRecognizer action.

The transition code at the TabBar controller class is the following:

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    if CanChangeTab {
        guard let fromView = tabBarController.selectedViewController!.view, let toView = viewController.view else {
            return false // Make sure you want this as false
        }

        if fromView != toView {
            if (tabBarController.prevIndex > tabBarController.selectedIndex) {
                UIView.transition(from: fromView, to: toView, duration: 0.3, options: [.transitionFlipFromLeft], completion: nil)
            } else {
                UIView.transition(from: fromView, to: toView, duration: 0.3, options: [.transitionFlipFromRight], completion: nil)
            }
        }
        return true
    } else {
        return false
    }
}

The gesture recogniser is calling the following function, from which the above code is not called:

@objc func swiped(_ gesture: UISwipeGestureRecognizer) {
    if (CanChangeTab) {
        self.tabBarController?.prevIndex = (self.tabBarController?.selectedIndex)!
        if gesture.direction == .left {
            if (self.tabBarController?.selectedIndex)! < 4 { // set your total tabs here
                self.tabBarController?.selectedIndex += 1
            }
        } else if gesture.direction == .right {
            if (self.tabBarController?.selectedIndex)! > 0 {
                self.tabBarController?.selectedIndex -= 1
            }
        }
    }
}

I cannot see what should be called or overridden to get the animations for the gesture base change too.


Solution

  • Ok. I have found the solution, using ViewController slide animation

    as Matt proposed.

    So using the extension + the animateToTab function in the extension and changing my swipe method it works just as expected.

       @objc func swiped(_ gesture: UISwipeGestureRecognizer) {
        if (CanChangeTab) {
            let thisTabController = self.tabBarController as! iBayTabController
    
            thisTabController.prevIndex = (thisTabController.selectedIndex)
            if gesture.direction == .left {
                if thisTabController.selectedIndex < 4 { // set your total tabs here
                    thisTabController.animateToTab(toIndex: thisTabController.selectedIndex+1)
                }
            } else if gesture.direction == .right {
                if (self.tabBarController?.selectedIndex)! > 0 {
                    thisTabController.animateToTab(toIndex: thisTabController.selectedIndex-1)
                }
            }
        }
    }