hidesBottomBarWhenPushed makes UITabBar “jump”

◇◆丶佛笑我妖孽 提交于 2019-12-09 23:31:45

问题


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!


回答1:


Having looked at the project in question I have found one way to make it work:

  1. Remove the 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.
  2. 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)
        }
    }
    
  3. 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.

  4. In the storyboard set the class type of the UITabBarController to your class of TabBarViewController so it gets the correct class when instantiated.

  5. 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.

  6. 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
    }()
    
  7. 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.




回答2:


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.



来源:https://stackoverflow.com/questions/48192749/hidesbottombarwhenpushed-makes-uitabbar-jump

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!