How to correct Tab Bar height issue on iPhone X

我与影子孤独终老i 提交于 2019-12-17 22:35:59

问题


I'm having an issue with my app when testing for iPhone X. I'm not sure how to adjust this issue, as well as not make it an issue for non iPhone X sizes. This only seems to be an issue on the iPhone X simulator.


回答1:


"File inspector" from right of Xcode storyboard, enable Safe Area guide layout to support your app in iPhone

This post describes really good.




回答2:


On iOS 12.1 I've solved this issue by overriding safeAreaInsets in the UITabBar subclass:

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



回答3:


Create a separate file with the following code:

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



回答4:


For iOS 11.3 this worked for me:

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



回答5:


I had a a similar issue. I was setting the selectionIndicatorImage in viewDidLoad(). Moving the code to viewDidLayoutSubviews() fixed my issue.




回答6:


Just align the bottom of the UITabBar to the superview, not to the safe area. If you align it to safe area it will be like this:

And when aligned to the superview, it will show correctly:

I think this is because Apple gave the tab bar items a default margin to the bottom if it is on iPhone X as they want the tab bar to be extended to the bottom of the screen to avoid a floating bar.




回答7:


This worked for me.

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



回答8:


The solution for me was that I had a custom UITabBar height set, something like this:

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

Remove it and the tab bar will display correctly on iPhone X.




回答9:


Follow below guidelines for setting the UITabbar selectionIndicatorImage.

  1. UITabBar.appearance().selectionIndicatorImage = #YOUR_IMAGE
  2. Make sure your image height is 48.

The default height of tabbar selectionIndicatorImage is 49, But in iPhone X set image height equals to 48.




回答10:


This worked for me as I am using a selection image.

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

Adding a bottom inset helps in my case. Hope this works for your as well. Thanks.




回答11:


invalidateIntrinsicContentSize of UITabBar in viewWillLayoutSubviews that may help you.

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



回答12:


In Constraints -

If you are giving bottom space with "Bottom Layout Guide", then this issue will occur.

Solution:

Give bottom space with respect to superview. This will work 100% perfect.




回答13:


There is UITabBar subclass that solves all my issues with 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
        }
    }

}
}



回答14:


Apple has now fixed this issue in iOS 12.1.1




回答15:


It's look crazy but I just need to remove this line in my code

self.view.layoutIfNeeded()

I just guess that call layoutIfNeeded on a view that doesn't appear in screen will make this problem happen. Anyway, solution from @mohamed-ali also work correctly. Thanks you so much.




回答16:


Add this code in 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
        }

and add this extension

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



回答17:


Put this into your UITabBarViewController to correct the TabBar height if your UIViewController is rotatable.

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



回答18:


I was facing this cosmetic problem above iOS 11.0 and below 12.0 only.

I was having a CustomTabBar class inherited from UITabBar. I override the frame method like below:

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

It resolved this issue in most of the iOS version 11.0 *




回答19:


Although my answer is late, But let me ensure you, if you are facing any issue like this on iphone x, xs or max screen, Make sure the image size you are uploading as selection must have height = width * 48pxHeight.



来源:https://stackoverflow.com/questions/47054707/how-to-correct-tab-bar-height-issue-on-iphone-x

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