hidesBottomBarWhenPushed 使 UITabBar "jump"

hidesBottomBarWhenPushed makes UITabBar "jump"

我有一个带有标签栏和导航栏的应用程序。

我有一个 BaseVC 和一个 DetailVC。我正在从 BaseVC 推送 DetailVC。我希望标签栏位于推送的 VC DetailVC 下方。我正在使用 hidesBottomBarWhenPushed 来实现它。它工作得很好,但由于某种原因,当它为推送设置动画时,标签栏仍然可见,并且当动画结束时标签栏被隐藏。我也希望它在动画中被推 VC。

我的代码是:

self.hidesBottomBarWhenPushed  = true
self.navigationController?.pushViewController(detailVC, animated: true)
self.hidesBottomBarWhenPushed = false

结果(bug)是这样的:

有人知道标签栏为什么会“跳跃”吗?谢谢!

在查看了相关项目后,我找到了一种使其工作的方法:

  1. TabBarViewController 中删除 viewWillLayoutSubviews,这样它就不再确定标签栏的高度,从而不会停止动画正常工作。
  2. 创建一个名为 MyTabBar(或任何你想要的)的新 swift 文件并将其放入其中:

    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. 创建一个名为 TabBarStoryboard(或其他名称)的故事板。它不会用于任何其他用途,只是用来存放您稍后创建的 UITabBarController。

  4. 在情节提要中,将 UITabBarController 的 class 类型设置为 TabBarViewController 的 class,以便在实例化时获得正确的 class。

  5. 在情节提要中,将属于 UITabBarController 的 UITabBar 的 class 类型设置为 MyTabBar,这样它在实例化时也是正确的 class。

  6. 在您的 RootViewController 中替换为:

    fileprivate let tabBarViewController = TabBarViewController()
    

    有了这个:

    fileprivate lazy var tabBarViewController: TabBarViewController = {
        let storyboard = UIStoryboard(name: "TabBarStoryboard", bundle: nil)
        return storyboard.instantiateViewController(withIdentifier: "MyTabBarController") as! TabBarViewController
    }()
    
  7. 在您的 TabBarViewController 中,将此添加到 viewDidLoad 的末尾以设置标签栏的高度:

        if let tabBar = self.tabBar as? MyTabBar {
            tabBar.tabBarHeight = self.tabBarHeight
        }
    

现在,如果你做对了所有事情,你应该有一个你想要的大小的标签栏,并且动画应该可以正常工作,因为标签栏的高度不再由 viewDidLayoutSubviews 方法控制。

我不得不使用故事板来保存基本的 UITabBarController,因为我找不到设置其 UITabBar class 的方法 属性 否则(如果有人知道方法,请添加评论.

如果这很难理解,我已将您的项目版本上传到保管箱,这是 link:PlayWiz-NewVersion.zip。小心,因为它会解压缩到相同的目录结构,所以将它解压缩到与原始文件夹不同的文件夹,否则你将丢失原始文件。

该方法对我来说似乎工作正常,我看不出有任何问题,但首先要彻底测试它。

我对上面的例子有一个更简单的变体(顺便干杯) 我在 viewDidLoad 中粘贴了所有内容,但您可以将其写得更漂亮。

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)
    }
}

现在,只需调用 hidesBottomBarWhenPushed = true 并推送所需的视图控制器。