【问题标题】:How to correct Tab Bar height issue on iPhone X如何纠正 iPhone X 上的标签栏高度问题
【发布时间】:2018-04-13 18:16:54
【问题描述】:

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

【问题讨论】:

  • 以编程方式使用不会影响此问题的 TabbarController
  • 你解决了这个问题吗?由于自定义标签栏高度,我遇到了这个问题
  • @ShangariC 你的问题和我的一样(自定义高度),你可以试试this,去掉viewWillLayoutSubviews的覆盖,改用它来应用自定义高度。

标签: ios swift xcode uistoryboard iphone-x


【解决方案1】:

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 { $0.activationState == .foregroundActive }
        .compactMap { $0 as? UIWindowScene }
        .first?.windows
        .filter { $0.isKeyWindow }
        .first
    
    override var safeAreaInsets: UIEdgeInsets {
        if let insets = keyWindow?.safeAreaInsets {
            if insets.bottom < bounds.height {
                cachedSafeAreaInsets = insets
            }
        }
        return cachedSafeAreaInsets
    }
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 很好的解决方案对我有用,虽然你永远不想在扩展中这样做
    【解决方案3】:

    Xcode故事板右侧的“文件检查器”,启用安全区域指南布局以支持您在iPhone中的应用

    This post 描述得非常好。

    【讨论】:

    • 听起来这个问题是重复的,为什么不这样标记呢?
    • @MartijnPieters 这两个问题是不同的概念,但指向相同的解决方案。
    • 重复都是同一个解决方案。
    • 这已被检查并且我的约束设置为安全区域,但我仍然在底部得到那个奇怪的差距。
    • 仅仅因为答案是重复的,并不一定会使问题重复。我发现这个问题很有用而且很独特。
    【解决方案4】:

    对于 iOS 11.3,这对我有用:

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

    【讨论】:

      【解决方案5】:

      在约束中 -

      如果您使用“底部布局指南”给底部空间,则会出现此问题。

      解决方案:

      相对于 superview 给底部空间。这将 100% 完美。

      【讨论】:

        【解决方案6】:

        这对我有用。

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

        【讨论】:

        • 这真是救了我的答案
        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

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

          当与超级视图对齐时,它会正确显示:

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

          【讨论】:

            【解决方案9】:

            按照以下指南设置 UITabbar selectionIndicatorImage。

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

            tabbar selectionIndicatorImage 的默认高度是 49,但在 iPhone X 中设置图像高度等于 48。

            【讨论】:

              【解决方案10】:

              我的解决方案是我设置了一个自定义的 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 上正确显示。

              【讨论】:

                【解决方案11】:

                在 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!
                    }
                }
                

                【讨论】:

                  【解决方案12】:

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

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

                  【讨论】:

                    【解决方案13】:

                    viewWillLayoutSubviews 中 UITabBar 的 invalidateIntrinsicContentSize 可能对您有所帮助。

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

                    【讨论】:

                    • 嗨 Nishant,尝试过这个,没有任何区别。
                    【解决方案14】:

                    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 { $0.frame }
                        if (state.first { $0.width == 0 } == nil) {
                            _subviewsFrames = state
                        } else {
                            zip(subviews, _subviewsFrames).forEach { (view, rect) in
                                view.frame = rect
                            }
                        }
                    
                    }
                    }
                    

                    【讨论】:

                      【解决方案15】:

                      Apple 现已在 iOS 12.1.1

                      中修复了此问题

                      【讨论】:

                      • 这在 iOS 12.1.4 中没有修复
                      • 可以确认这个问题在 iOS 12.1.1 上已修复(在两台 iPhone 8s 上测试,一个在 12.1,另一个在 12.1.1)...不要告诉我苹果打破了它再次...
                      • 在 iOS 13 上坏了
                      • @tww0003,它对我有用。你能分享一下你是怎么做的吗?
                      【解决方案16】:

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

                      self.view.layoutIfNeeded()
                      

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

                      【讨论】:

                        【解决方案17】:

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

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

                        在我的情况下,添加底部插图会有所帮助。 希望这也适用于您。 谢谢。

                        【讨论】:

                          【解决方案18】:

                          虽然我的回答迟了,但让我向您保证,如果您在 iphone x、xs 或 max 屏幕上遇到任何此类问题,请确保您作为选择上传的图像尺寸必须具有高度 = 宽度 * 48pxHeight。

                          【讨论】:

                            【解决方案19】:

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

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

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

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

                            【讨论】:

                              【解决方案20】:

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

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

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

                              它在大部分 iOS 11.0 版本中解决了这个问题 *

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2018-10-12
                                • 2010-12-03
                                • 2013-11-20
                                相关资源
                                最近更新 更多