如何在iOS 11中正确设置UINavigationBar高度

如何在iOS 11中正确设置UINavigationBar高度,ios,objective-c,uinavigationbar,ios11,Ios,Objective C,Uinavigationbar,Ios11,在我的iOS 9+应用程序中,我在一些UIViewControllers中“手动”使用UINavigationBar(=将它们直接放在VC中,而不是使用UINavigationViewController) 使用一个简单的控件为这样一个UINavigationBar设置一个高度以前是没有问题的。然而,在iOS 11中,条本身仍然正确地使用指定的大小,但是内容不再正确定位(现在对齐到顶部) 你知道如何解决这个问题吗? 编辑: 我很确定,这不是“”的重复,这个问题解决了UINavigationBa

在我的iOS 9+应用程序中,我在一些
UIViewController
s中“手动”使用
UINavigationBar
(=将它们直接放在VC中,而不是使用
UINavigationViewController

使用一个简单的控件为这样一个
UINavigationBar
设置一个高度以前是没有问题的。然而,在iOS 11中,条本身仍然正确地使用指定的大小,但是内容不再正确定位(现在对齐到顶部)

你知道如何解决这个问题吗?

编辑:

我很确定,这不是“”的重复,这个问题解决了
UINavigationBar
子类的问题,而我直接使用
UINavigationBar
。另外,所描述的问题似乎在Beta 4中解决了,而我在Beta 6中遇到了这个问题

编辑2:


同时,我实现了由提出的
UINavigationBar
子类。然而,这并没有解决我的问题。子视图框架似乎都设置正确(无需手动执行),但布局仍然被破坏。因此,手动设置帧没有任何区别

我现在正面临这个问题。 起初,这似乎是酒吧中另一个与我的冲突的高度限制,但我的优先级为1000,所以这似乎不是问题所在。 然后我在UINavigationBar“UINavigationBarContentView”中看到另一个视图,该视图的高度大于0

然后我尝试将navigationBar.clipsToBounds=true设置为有效,因为父视图具有正确的高度

编辑:如果需要显示条的阴影,则需要cliptobunds=false。在这种情况下,您可以将NavigationBar子类化

import UIKit

class SecondNavigationBar: UINavigationBar {
    override func layoutSubviews() {
        super.layoutSubviews()

        for subview in self.subviews {
            var stringFromClass = NSStringFromClass(subview.classForCoder)
            print("--------- \(stringFromClass)")
            if stringFromClass.contains("BarBackground") {
                subview.frame = self.bounds
            } else if stringFromClass.contains("UINavigationBarContentView") {
                subview.frame = self.bounds
            }
        }
    }
}

我也有这个问题。我是这样解决的:

 -(void)layoutSubviews{
        [super layoutSubviews];
        CGRect rectStatus = [[UIApplication sharedApplication] statusBarFrame];
        if (rectStatus.size.height==44.f) {

        }else{
            if (@available(iOS 11.0, *)) {
                for ( UIView*aView in self.subviews) {
                    if ([NSStringFromClass(aView.classForCoder) isEqualToString:@"_UINavigationBarContentView"]) {
                        aView.frame = CGRectMake( 0,20,aView.frame.size.width,44);
                    }
                    else if ([NSStringFromClass(aView.classForCoder) isEqualToString:@"_UIBarBackground"]) {
                        aView.frame = CGRectMake(0,0,aView.frame.size.width, 64);
                    }
                }
            }
        }
    }

在iOS 11中,当您在UIViewController中使用自定义UINavigationBar时,我们可以直接覆盖UINavigationBar子类中的
barPosition
(返回UIBarPositionTopAttached而不是默认值UIBarPositionTop) 像这样:

- (UIBarPosition)barPosition {
    return UIBarPositionTopAttached;
}
布局代码如下所示:

    NSLayoutConstraint* a = [navigationBar.widthAnchor constraintEqualToAnchor:viewController.view.widthAnchor];
    NSLayoutConstraint *b = [navigationBar.centerXAnchor constraintEqualToAnchor:viewController.view.centerXAnchor constant:0];
    NSLayoutConstraint* c = [navigationBar.centerYAnchor constraintEqualToAnchor:viewController.view.topAnchor constant:X];

   [NSLayoutConstraint activateConstraints:@[a,b,c]];   
不要设置它的高度,它应该始终为44

它在iOS 11中运行良好。视图层次结构与UINavigationController的相同。
但它在iOS 11下不起作用。我们需要设置UINavigationBarDelegate以返回UIBarPositionTopAttached in

- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar;  
-(UIBAR位置)定位栏:(id)栏;

不要更改条形图的高度,只需在其顶部使用自定义视图或隐藏条形图,低于11的ios似乎存在此问题。这将是一个解决方案,但如果
UINavigationBar
使用某种渐变背景,则会非常麻烦。您是否看到iOS 10或更低版本的问题?我想说的是,iOS 10-工作正常,iOS 11的布局被破坏了。我的解决方案可能与此重复:除了如何更改uinavigationbar的高度外,您解释了很多事情:(很抱歉,我不得不对此投了否决票。我坚信这是一种极其危险和不稳定的黑客行为,可能会让你被拒绝,或者更糟糕的是,在任何时候或通过任何iOS更新完全破坏你的应用程序布局。)