0

Why doesn't animation work properly (black screen) when I try to change views via selectedIndex property but it works if I change them when tapping tabBar items?

(I'm a beginner in swift. Sorry for the looong post, I want to be as clear as possible)

CONTEXT

What I want to achieve:

I want views associated to tabBar items [0], [1], [n...] to have an animation for presentation whether they are changed when pressing a tabBar item or selectedItem property is changed programatically.


What has worked so far:

I made a custom class for tabBar and overrided the 'shouldSelect viewController: UIViewController' method for placing the animation.

The animation works fine everytime a tabBar item is pressed. It shows the destinationView above the sourceView like it was presented doing a show segue.

extension MySubclassedTabBarController: UITabBarControllerDelegate  {

    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {

        if let sourceView = selectedViewController?.view, let destinationView = viewController.view, sourceView != destinationView {
            sourceView.superview?.insertSubview(destinationView, aboveSubview: sourceView)
            destinationView.transform = CGAffineTransform(translationX: sourceView.frame.size.width, y: 0)
            UIView.animate(withDuration: 0.25,
                           delay: 0.0,
                           options: .curveEaseInOut,
                           animations: { destinationView.transform = CGAffineTransform(translationX: 0, y: 0) },
                           completion: nil)
        }
        return true
    }
}

What has not worked (properly):

Additionally to changing views when pressing tabBar items, I want to change views associated to tabBar by setting selectedIndex property programatically in an UIButton action.

If I load the app for the very first time and try to change views via alphaButton, the screen goes black (sourceView dissapears) and then shows the animated destinationView.

class FirstViewController () {

    @IBAction func alphaButton(_ sender: Any) {

        tabBarController?.selectedIndex = 1

        if let sourceView = view, let destinationView = tabBarController?.selectedViewController?.view, sourceView != destinationView {
            sourceView.superview?.insertSubview(destinationView, aboveSubview: sourceView)
            destinationView.transform = CGAffineTransform(translationX: sourceView.frame.size.width, y: 0)
            UIView.animate(withDuration: 0.25,
                           delay: 0.0,
                           options: .curveEaseInOut,
                           animations: { destinationView.transform = CGAffineTransform(translationX: 0, y: 0) },
                           completion: nil)
        }
    }
}

The transition won't work properly if the destination view hasn't been presented before.

In other words, it works correctly if:

  1. Run the app
  2. Tap tabBarItem[1] (secondViewController)
  3. Return to firstViewController by tapping tabBarItem[0]
  4. Tap the alphaButton (which will send me again to secondViewController and show transition presenting the view above the previous view, which is, in this case, FirstViewController)

It won't work properly if:

  1. Run the app
  2. Tap alphaButton (It shows the transition and presents the view showing the animation but the screen goes black first)

Why does it show a black screen? How can I avoid that?

Suggestions to achieve what I want in other ways are welcome

Thank you :)

Ryoko
  • 75
  • 6

1 Answers1

-1

Solved it.

Using this (in alphaButton):

destinationView.superview?.insertSubview(sourceView, belowSubview: destinationView)

Instead of this:

sourceView.superview?.insertSubview(destinationView, aboveSubview: sourceView)
Ryoko
  • 75
  • 6
  • But the problem really is that none of this is the correct way to do a custom animation when changing tab bar items. The correct way is to write a _custom transition animation_. See for example my answer here: https://stackoverflow.com/a/51580236/341994 – matt Aug 13 '18 at 14:50
  • So the reason behind the black screen was all about the way I was implementing the animation? Thank you so much @matt, I'll check it out. – Ryoko Aug 13 '18 at 15:32