在Xcode11 / iOS13或13.1中自定义UITabBar高度

3

我曾经使用以下代码来调整我的选项卡栏的高度。然而,在我升级到Xcode 11并且使用swift 5后,UI不再正确显示。

class MyTabBarController: UITabBarController {

    private lazy var defaultTabBarHeight = { [unowned self] in
        return self.tabBar.frame.size.height
    }()

    let higherTabBarInset: CGFloat = 24
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        let newTabBarHeight = defaultTabBarHeight + higherTabBarInset
        var newFrame = tabBar.frame
        newFrame.size.height = newTabBarHeight
        newFrame.origin.y = view.frame.size.height - newTabBarHeight
        tabBar.items?.forEach({e in
            e.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -(higherTabBarInset / 2))
        })
    }
}

它应该像这样出现,选项卡栏的高度为72:

expected display

然而,使用Xcode 11在iOS 12中的效果是这样的,选项卡栏高度恢复到默认的49:

abnormal display under ios 12

在iOS 13中,即使我的应用程序仅设置为纵向布局且目标设备仅为iPhone,它也会显示为.inlineLayoutAppearance。我的自定义字体也会回到系统默认字体。与iOS 12一样,UITabBar的高度也会恢复默认值49:

abnormal display under ios 13

我参考了这个类似的问题,但是那个解决方案对我不起作用,而且看起来也不像一个正确的解决方案。
另外一件我不理解的事情是,当我尝试使用以下代码设置UITabBarItem的外观时:
tabBar.items?.forEach({e in
    if #available(iOS 13.0, *) {
        let appearance = UITabBarItemAppearance()
        appearance.configureWithDefault(for: .stacked)
        e.standardAppearance = appearance
    }
})

我收到了一个错误,提示“无法将类型 'UITabBarItemAppearance' 分配给类型 'UITabBarAppearance?'”。然后我发现,即使我的迭代变量“e”的类型是“UITabBarItem”,它的外观类型也是“UITabBarAppearance?”... 我找不到一种方法来设置我的UITabBarItem的外观,这真的很令人困惑...
有人知道这是否有合理的原因,或者这是可能的错误吗?感谢任何答案。

类 TabBar: UINavigationBar { override var intrinsicContentSize: CGSize { return CGSize(width: super.intrinsicContentSize.width, height: 72) } } - SPatel
我在iOS 13中遇到了同样的问题,UITabBar无法适当地调整大小。在viewWillLayoutSubviews()而不是viewDidLayoutSubview()中设置选项卡栏高度对我很管用。 - Brittany
2个回答

2

当使用viewDidLayoutSubviews()而不是viewWillLayoutSubviews()设置新框架时,似乎我可以成功地设置不同的选项卡栏高度。

至于设置文本偏移量,请尝试

if #available(iOS 13, *) {
   let appearance = self.tabBar.standardAppearance.copy()
   appearance.stackedLayoutAppearance.normal.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -4)
   tabBar.standardAppearance = appearance
}

更改为viewDidLayoutSubviews似乎对我的应用程序没有起作用...标题仍然在图标的右侧,而不是底部,即使我使用负水平值设置UIOffset,标题仍然不会向左移动。只有垂直偏移量可更改我的选项卡栏。 - whitney13625

2

这就是我最终解决了选项卡栏高度问题的方法,但是标题位置还没有解决,目前我只能使用带有文本的图标图像。

@IBDesignable class MyTabBar: UITabBar {

    let higherTabBarInset: CGFloat = 24

    lazy var isIphoneXOrHigher: Bool = {
        return UIDevice().userInterfaceIdiom == .phone && UIScreen.main.nativeBounds.height >= 2436
    }()

    lazy var TAB_BAR_HEIGHT: CGFloat = {
        // Return according to default tab bar height
        if GlobalData.isIphoneXOrHigher {
            return 83 + higherTabBarInset
        }
        else {
            return 49 + higherTabBarInset
        }
    }()

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        if #available(iOS 13.0, *) {
            self.standardAppearance.compactInlineLayoutAppearance = UITabBarItemAppearance.init(style: .stacked)
            self.standardAppearance.inlineLayoutAppearance = UITabBarItemAppearance.init(style: .stacked)
            self.standardAppearance.stackedLayoutAppearance = UITabBarItemAppearance.init(style: .stacked)
            self.standardAppearance.stackedItemPositioning = .centered
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        var size = super.sizeThatFits(size)
        size.height = TAB_BAR_HEIGHT
        return size
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        self.items?.forEach({ e in
            if #available(iOS 13.0, *) {
                e.standardAppearance = self.standardAppearance
            }
            else {
                e.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -(higherTabBarInset / 2))
            }
        })
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接