如何更正 iPhone X 上的 Tab Bar 高度问题

How to correct Tab Bar height issue on iPhone X

我的应用程序在测试 iPhone X 时遇到问题。我不确定如何调整这个问题,以及如何不让它成为非 iPhone 的问题X尺寸。这似乎只是 iPhone X 模拟器上的问题。

invalidateIntrinsicContentSize of UITabBar in viewWillLayoutSubviews 可能对你有帮助。

 override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    self.tabBar.invalidateIntrinsicContentSize()
}

"File inspector" 从 Xcode 故事板右侧开始,启用安全区域指南布局以支持您在 iPhone

中的应用

描述的真好。

受限 -

如果您将底部 space 与 "Bottom Layout Guide" 一起使用,则会出现此问题。

解法:

关于 superview 的底部 space。这将 100% 完美。

我的解决方案是自定义 UITabBar 高度设置,如下所示:

  override func viewWillLayoutSubviews() {            
        var tabFrame = tabBar.frame
        tabFrame.size.height = 60
        tabFrame.origin.y = self.view.frame.size.height - 60
        tabBar.frame = tabFrame
    }

删除它,标签栏将在 iPhone X 上正确显示。

这对我有用,因为我正在使用选择图像。

tabBar.selectionIndicatorImage = UIImage.imageWithColor(color: UIColor.NewDesignColor.yellow, size: tabBarItemSize).resizableImage(withCapInsets: UIEdgeInsets.init(top: 0, left: 0, bottom: 20, right: 0))

添加底部插图对我的情况有帮助。 希望这也适用于您。 谢谢

对于 iOS 11.3 这对我有用:

func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    tabBar.invalidateIntrinsicContentSize()
}

我遇到了类似的问题。我在 viewDidLoad() 中设置了 selectionIndicatorImage。将代码移至 viewDidLayoutSubviews() 解决了我的问题。

使用以下代码创建一个单独的文件:

extension UITabBar {
    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        super.sizeThatFits(size)
        guard let window = UIApplication.shared.keyWindow else {
            return super.sizeThatFits(size)
        }
        var sizeThatFits = super.sizeThatFits(size)
        sizeThatFits.height = window.safeAreaInsets.bottom + 40
        return sizeThatFits
    }
}

只需将 UITabBar 的底部与超级视图对齐,而不是与安全区域对齐。如果将它对齐到安全区域,它将是这样的:

并且当与父视图对齐时,它将正确显示:

我认为这是因为 Apple 为标签栏项目提供了默认的底部边距,如果它位于 iPhone X 上,因为他们希望将标签栏扩展到屏幕底部以避免浮动栏.

按照以下指南设置 UITabbar selectionIndicatorImage。

  1. UITabBar.appearance().selectionIndicatorImage = #YOUR_IMAGE
  2. 确保您的图片高度为 48。

tabbar selectionIndicatorImage默认高度为49,但在iPhoneX中设置图片高度等于48。

iOS 12.1 我已经通过覆盖 UITabBar 子类中的 safeAreaInsets 解决了这个问题:

class TabBar: UITabBar {
    private var cachedSafeAreaInsets = UIEdgeInsets.zero

    override var safeAreaInsets: UIEdgeInsets {
        let insets = super.safeAreaInsets
    
        if insets.bottom < bounds.height {
            cachedSafeAreaInsets = insets
        }
    
        return cachedSafeAreaInsets
    }
}

iOS 13.0 以上,

class TabBar: UITabBar {
    private var cachedSafeAreaInsets = UIEdgeInsets.zero

    let keyWindow = UIApplication.shared.connectedScenes
        .filter { [=11=].activationState == .foregroundActive }
        .compactMap { [=11=] as? UIWindowScene }
        .first?.windows
        .filter { [=11=].isKeyWindow }
        .first
    
    override var safeAreaInsets: UIEdgeInsets {
        if let insets = keyWindow?.safeAreaInsets {
            if insets.bottom < bounds.height {
                cachedSafeAreaInsets = insets
            }
        }
        return cachedSafeAreaInsets
    }
}

UITabBar 子类解决了我所有关于 iPhone X iOS 11 / iOS 12

的问题
class TabBar: UITabBar {

private var _safeAreaInsets = UIEdgeInsets.zero
private var _subviewsFrames: [CGRect] = []

@available(iOS 11.0, *)
override func safeAreaInsetsDidChange() {
    super.safeAreaInsetsDidChange()

    if _safeAreaInsets != safeAreaInsets {
        _safeAreaInsets = safeAreaInsets

        invalidateIntrinsicContentSize()
        superview?.setNeedsLayout()
        superview?.layoutSubviews()
    }
}

override func sizeThatFits(_ size: CGSize) -> CGSize {
    var size = super.sizeThatFits(size)
    if #available(iOS 12.0, *) {
        let bottomInset = safeAreaInsets.bottom
        if bottomInset > 0 && size.height < 50 && (size.height + bottomInset < 90) {
            size.height += bottomInset
        }
    }
    return size
}

override var frame: CGRect {
    get {
        return super.frame
    }
    set {
        var tmp = newValue
        if let superview = superview, tmp.maxY !=
                superview.frame.height {
            tmp.origin.y = superview.frame.height - tmp.height
        }

        super.frame = tmp
    }
}

override func layoutSubviews() {
    super.layoutSubviews()
    let state = subviews.map { [=10=].frame }
    if (state.first { [=10=].width == 0 } == nil) {
        _subviewsFrames = state
    } else {
        zip(subviews, _subviewsFrames).forEach { (view, rect) in
            view.frame = rect
        }
    }

}
}

Apple 现已在 iOS 12.1.1

中修复了此问题

这看起来很疯狂,但我只需要在我的代码中删除这一行

self.view.layoutIfNeeded()

我只是猜测在屏幕上没有出现的视图上调用 layoutIfNeeded 会导致这个问题发生。 无论如何,@mohamed-ali 的解决方案也可以正常工作。非常感谢。

在viewDidLoad中添加这段代码

DispatchQueue.main.async {
            let size = CGSize(width: self.tabBar.frame.width / numberOfTabsFloat,
                              height: self.tabBar.frame.height)
            let image = UIImage.drawTabBarIndicator(color: UIColor.white,
                                                   size: size,
                                                   onTop: false)
            UITabBar.appearance().selectionIndicatorImage = image
            self.tabBar.selectionIndicatorImage = image
        }

并添加此扩展程序

extension UIImage{
    //Draws the top indicator by making image with filling color
    class func drawTabBarIndicator(color: UIColor, size: CGSize, onTop: Bool) -> UIImage {
        let indicatorHeight = size.height
        let yPosition = onTop ? 0 : (size.height - indicatorHeight)

        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(CGRect(x: 0, y: yPosition, width: size.width, height: indicatorHeight))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image!
    }
}

如果您的 UIViewController 是可旋转的,请将其放入您的 UITabBarViewController 以更正 TabBar 高度。

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        tabBar.sizeToFit()
    }

这对我有用。

[self.tabBar.bottomAnchor constraintEqualToAnchor:self.view.layoutMarginsGuide.bottomAnchor].active = YES;

我只在 iOS 11.0 和 12.0 以下遇到这个外观问题。

我有一个继承自 UITabBar 的 CustomTabBar class。 我重写了如下的框架方法:

- (CGRect)frame{
    return self.bounds;
}

它在大多数 iOS 版本 11.0 *

中解决了这个问题

虽然我的回答晚了,但我向您保证,如果您在 iphone x、xs 或最大屏幕上遇到任何此类问题,请确保您上传的图片尺寸必须符合高度 = 宽度 * 48pxHeight.

在尝试了一些解决方案后,对我有用的是将以下行添加到 viewDidLoad:

[self.tabBar.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;

Jonah 和 Mehul Thakkar 的回答为我指明了正确的方向。

注意:我在情节提要中只有一个空白的标签栏控制器。标签栏图像和视图控制器是使用 tabBarItem 属性设置的(例如,视图控制器上的 tabBarItem.title)。