Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何纠正iPhone X上的选项卡栏高度问题_Ios_Swift_Xcode_Uistoryboard_Iphone X - Fatal编程技术网

Ios 如何纠正iPhone X上的选项卡栏高度问题

Ios 如何纠正iPhone X上的选项卡栏高度问题,ios,swift,xcode,uistoryboard,iphone-x,Ios,Swift,Xcode,Uistoryboard,Iphone X,在测试iPhoneX时,我的应用程序出现问题。我不确定如何调整这个问题,也不确定如何使它成为非iPhoneX尺寸的问题。这似乎只是iPhoneX模拟器上的一个问题 视图中UITabBar的invalidateIntrinsicContentSize将布局子视图,这可能会对您有所帮助 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() self.tabBar.invalidateIntr

在测试iPhoneX时,我的应用程序出现问题。我不确定如何调整这个问题,也不确定如何使它成为非iPhoneX尺寸的问题。这似乎只是iPhoneX模拟器上的一个问题


视图中UITabBar的invalidateIntrinsicContentSize将布局子视图,这可能会对您有所帮助

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

“文件检查器”位于Xcode情节提要的右侧,启用安全区域指南布局以支持iPhone中的应用程序

非常好地描述了它。

在约束中-

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

解决方案:


为superview提供底部空间。这将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的底部与superview对齐,而不是与安全区域对齐。如果将其与安全区域对齐,则如下所示:

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

当与superview对齐时,它将正确显示:


我认为这是因为苹果在iPhone X上给了标签栏项目一个默认的底部边距,因为他们希望标签栏延伸到屏幕底部,以避免浮动条。

请遵循以下设置UITabbar selectionIndicatorImage的指导原则

  • uitabar.appearance()。选择指示图像=#您的图像
  • 确保图像高度为48。

  • tabbar selectionIndicatorImage的默认高度为49,但在iPhone X中,将图像高度设置为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
        }
    }
    
    class选项卡栏:uitabar{
    private var cachedSafeAreaInsets=UIEdgeInsets.zero
    覆盖var安全区域插图:UIEdgeInsets{
    let insets=超级安全区域insets
    如果insets.bottom
    对于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
        }
    }
    
    class选项卡栏:uitabar{
    private var cachedSafeAreaInsets=UIEdgeInsets.zero
    让keyWindow=UIApplication.shared.connectedScenes
    .filter{$0.activationState==.foregroundActive}
    .compactMap{$0作为?UIWindowScene}
    .第一个?.窗户
    .filter{$0.isKeyWindow}
    .首先
    覆盖var安全区域插图:UIEdgeInsets{
    如果let insets=keyWindow?.safeAreaInsets{
    如果insets.bottom
    有一个
    uitabar
    子类解决了我在iphonex
    ios11上的所有问题

    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
            }
        }
    
    }
    }
    
    class选项卡栏:uitabar{
    私有变量_safeAreaInsets=UIEdgeInsets.zero
    私有变量\u子视图框架:[CGRect]=[]
    @可用(iOS 11.0,*)
    重写函数safeAreaInsetsDidChange(){
    super.safeareainsertsdidchange()
    如果_safeAreaInsets!=safeAreaInsets{
    _安全区域插图=安全区域插图
    InvalidateIntriseContentSize()无效
    superview?.setNeedsLayout()
    superview?.layoutSubviews()
    }
    }
    重写func sizeThatFits(usize:CGSize)->CGSize{
    var size=super.sizeThatFits(大小)
    如果可用(iOS 12.0,*){
    让bottomInset=安全区域inset.bottom
    如果底部插图>0&&size.height<50&&size.height+底部插图<90){
    尺寸.高度+=底部插图
    }
    }
    返回大小
    }
    覆盖变量帧:CGRect{
    得到{
    返回超级帧
    }
    设置{
    var tmp=新值
    如果让superview=superview,则tmp.maxY=
    superview.frame.height{
    tmp.origin.y=superview.frame.height-tmp.height
    }
    super.frame=tmp
    }
    }
    覆盖func布局子视图(){
    super.layoutSubviews()
    让state=subviews.map{$0.frame}
    如果(state.first{$0.width==0}==nil){
    _子视图框架=状态
    }否则{
    zip(子视图,_子视图框架).forEach{(视图,rect)in
    view.frame=rect
    }
    }
    }
    }
    
    苹果现在已经在iOS 12.1.1中解决了这个问题

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

    self.view.layoutIfNeeded()
    
    我只是猜测,在屏幕上没有显示的视图上需要调用layoutifn会导致这个问题发生。
    无论如何,@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是可旋转的,则将其放入UIAbbarViewController以更正选项卡栏高度

    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类。 我覆盖框架方法,如下所示:

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

    虽然我的答案晚了,但我可以向您保证,如果您在iphone x、xs或max屏幕上遇到类似的问题,请确保您上传的图像大小必须为height=width*48pxHeight,对我有效的方法是向viewDidLoad添加以下行:

    [self.tabBar.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
    
    约拿和梅胡尔·塔卡尔的回答为我指明了正确的方向

    注意:我在情节提要中只有一个空白的选项卡栏控制器。选项卡栏“图像和视图控制”