Reputation: 1464
I have an app with a tabbar and a navbar.
I have a BaseVC
and a DetailVC
. I'm pushing DetailVC
from BaseVC
. I want the tabbar to be under the pushed VC DetailVC
. I'm using hidesBottomBarWhenPushed
to achieve it. It works great, but for some reason while it's animating the push the tabbar is still visible and just when the animation ends the tabbar is hidden. I want it to be under the pushed VC in the animation too.
My code is:
self.hidesBottomBarWhenPushed = true
self.navigationController?.pushViewController(detailVC, animated: true)
self.hidesBottomBarWhenPushed = false
And the result (the bug) is this:
Anyone has an idea why the tabbar "jumps"? Thank you!
Upvotes: 2
Views: 1591
Reputation: 1079
I have a simpler variation of the above example (cheers by the way) I pasted everything in viewDidLoad, but you can write it prettier.
class TabBarController: UITabBarController {
override func viewDidLoad() {
// create the normal buttons (controllers)
let viewControllers = [UINavigationController(rootViewController: firstButton), UINavigationController(rootViewController: secontButton)]
self.viewControllers = viewControllers
// create the middle rounded button
self.tabBar.addSubview(addItemButton)
// setup constraints
addItemButton.widthAnchor.constraint(equalToConstant: 64).isActive = true
addItemButton.heightAnchor.constraint(equalToConstant: 64).isActive = true
tabBar.centerXAnchor.constraint(equalTo: self.addItemButton.centerXAnchor).isActive = true
tabBar.topAnchor.constraint(equalTo: self.addItemButton.centerYAnchor, constant: -8).isActive = true
}
extension UITabBar {
// fix clicking the (+) external to the tabbar bounds
override open func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if (!self.clipsToBounds && !self.isHidden && self.alpha > 0.0) {
let subviews = self.subviews.reversed()
for member in subviews {
let subPoint = member.convert(point, from: self)
if let result:UIView = member.hitTest(subPoint, with:event) {
return result;
}
}
}
return super.hitTest(point, with: event)
}
// this fixes the "jumping" tabBar when using the "hidesBottomBarWhenPushed = true"
override open func sizeThatFits(_ size: CGSize) -> CGSize {
let superSize = super.sizeThatFits(size)
return CGSize(width: superSize.width, height: 85)
}
}
Now, just call hidesBottomBarWhenPushed = true and push the desired view controller.
Upvotes: 1
Reputation: 4711
Having looked at the project in question I have found one way to make it work:
viewWillLayoutSubviews
from the TabBarViewController
so that it is not determining the height of the tab bar anymore and thus not stopping the animation working correctly.Create a new swift file called MyTabBar (or whatever you want) and put this in it:
import UIKit
class MyTabBar: UITabBar {
var tabBarHeight: CGFloat = 100
override func sizeThatFits(_ size: CGSize) -> CGSize {
let superSize = super.sizeThatFits(size)
return CGSize(width: superSize.width, height: self.tabBarHeight)
}
}
Create a storyboard called TabBarStoryboard (or whatever). It's not going to be used for anything other then to hold a UITabBarController which you later create.
In the storyboard set the class type of the UITabBarController to your class of TabBarViewController
so it gets the correct class when instantiated.
In the storyboard set the class type of the UITabBar that belongs to the UITabBarController to MyTabBar so that it too is the correct class when instantiated.
In your RootViewController replace this:
fileprivate let tabBarViewController = TabBarViewController()
with this:
fileprivate lazy var tabBarViewController: TabBarViewController = {
let storyboard = UIStoryboard(name: "TabBarStoryboard", bundle: nil)
return storyboard.instantiateViewController(withIdentifier: "MyTabBarController") as! TabBarViewController
}()
In your TabBarViewController add this to the end of the viewDidLoad
to set the height of the tab bar:
if let tabBar = self.tabBar as? MyTabBar {
tabBar.tabBarHeight = self.tabBarHeight
}
Now if you get all that correct you should have a tab bar the size you want and the animation should work correctly because the height of tab bar is not longer controlled by the viewDidLayoutSubviews method.
I had to use a storyboard to hold the basic UITabBarController because I couldn't find a way to set the class of its UITabBar property otherwise (if anyone knows a way add a comment.
In case this is difficult to follow I have uploaded my version of your project to dropbox and this is the link: PlayWiz-NewVersion.zip. Be careful as it will unzip to the same directory structure so extract it to a different folder than the original otherwise you will lose the original.
That method appears to work correctly for me and I see no reason for there to be any problem but test it thoroughly first.
Upvotes: 5