以编程方式获取导航栏的高度

122 objective-c uinavigationbar uinavigationcontroller ios swift

我知道更多视图控制器(导航栏)的存在会推动UIView的高度.我也知道这个高度= 44px.我也发现这种下推保持了[self.view].frame.origin.y = 0.

那么如何确定此导航栏的高度,而不仅仅是将其设置为常量?

或者,更短的版本,如何确定我的UIView显示在顶部的导航栏?


灯泡开始亮了.不幸的是,我没有找到纠正问题的统一方法,如下所述.

我相信我的整个问题都集中在我的autoresizingMasks上.并且我得出结论的原因是存在相同的症状,有或没有UIWebView.而这种症状是肖像的一切都是桃色的.对于Landscape,最底部的UIButton在TabBar后面弹出.

例如,在一个UIView上,我从上到下:

UIView - 弹簧设置(默认情况下)和没有支柱

UIScrollView - 如果我设置了两个弹簧,并清除了其他所有弹簧(如UIView),那么UIButton就会闯入它上方的物体上.如果我清除了所有内容,那么UIButton就可以了,但是最顶层的东西隐藏在StatusBar后面只设置顶部支柱,UIButton弹出Tab Bar后面.

UILabel和UIImage接下来垂直 - 顶部支撑设置,在其他地方灵活

只是为少数拥有UIWebView的图片完成:

UIWebView - Struts:顶部,左侧,右侧弹簧:两者

UIButton - 没有设置,即到处灵活

虽然我的灯泡昏暗,但似乎有希望.


请耐心等待,因为我需要更多的空间而不是简短的回复评论.

感谢您试图了解我真正想要捕获的东西......所以这里有.

1)每个UIViewController(一个TabBar应用程序)都有一个UIImage,一些文本和顶部的任何东西.另一个共同点是底部的UIButton.在一些UIViewControllers上,我在UIButton上面有一个UIWebView.

所以,UIImage,文本等UIWebView(在SOME上)UIButton

围绕以上所有是UIScrollView.

2)对于那些拥有UIWebView的人,其autoresizingMask看起来像:

   —
   |
   —

   ^
   |
   |
Run Code Online (Sandbox Code Playgroud)

| - | ←----→| - | | | V UIButton的面具没有任何设置,即在任何地方都很灵活

在我的-viewDidLoad中,我调用了我的-repositionSubViews,我在其中执行以下操作:

如果没有UIWebView,除了将我放置在IB中的UIButton放在中心之外,我什么都不做.

如果我有UIWebView,那么我确定其*content*Height并设置其框架以包含整个内容.

UIScrollView *scrollViewInsideWebView = [[webView_ subviews] lastObject];
webViewContentHeight = scrollViewInsideWebView.contentSize.height;
[webView_ setFrame:CGRectMake(webViewOriginX, webViewOriginY,
                          sameWholeViewScrollerWidth, webViewContentHeight)]
Run Code Online (Sandbox Code Playgroud)

一旦我这样做,然后我以编程方式向下推UIButton,使其最终放在UIWebView下面.

一切正常,直到我将它从肖像旋转到风景.

我在-didRotateFromInterfaceOrientation中调用了我的-repositionSubViews.

为什么我的UIWebView的内容高度不会随着旋转而改变?

从纵向到横向,内容宽度应该扩展,内容高度应该缩小.它视觉上应该如此,但不是根据我的NSLog.

无论如何,无论是否有UIWebView,我所谈到的按钮在横向模式下移动到TabBar下方,但它不会向上滚动以便看到.当我"大力"滚动时,我在TabBar后面看到它,但随后它"退回"TabBar后面.

最后一点,这就是我询问TabBar和NavigationBar高度的原因,因为TabBar将自己置于UIView的底部,而NavigationBar将UIView向下推.

现在,我要在这里添加一两条评论,因为它们之前没有意义.

没有UIWebView,我将所有内容保留为IB所见.

使用UIWebView,我将UIWebView的frame.height增加到其contentHeight,并向上调整围绕所有子视图的周围UIScrollView的高度.

那么你有它.

Sum*_*Sum 243

做这样的事情?

    NSLog(@"Navframe Height=%f",
        self.navigationController.navigationBar.frame.size.height);
Run Code Online (Sandbox Code Playgroud)

swift版本位于此处

  • 我知道这并没有解决他提出的问题,但似乎他正在寻找导航栏是否被隐藏.如果是这样,他可以使用self.navigationController.navigationBarHidden希望完全这有助于某人:) (2认同)
  • 在iOS 7+中,您可能还需要考虑20px状态栏,具体取决于您的应用程序 (2认同)

Kru*_*nal 76

使用iPhone-X,顶栏(导航栏+状态栏)的高度会发生变化(增加).

如果您想要顶部条的精确高度(导航栏+状态栏),请尝试此操作:

Objective-C的

extension UIViewController {

    /**
     *  Height of status bar + navigation bar (if navigation bar exist)
     */

    var topbarHeight: CGFloat {
        return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特4

CGFloat topbarHeight = ([UIApplication sharedApplication].statusBarFrame.size.height +
       (self.navigationController.navigationBar.frame.size.height ?: 0.0));
Run Code Online (Sandbox Code Playgroud)

为方便起见,请尝试使用此UIViewController扩展

let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
        (self.navigationController?.navigationBar.frame.height ?? 0.0)
Run Code Online (Sandbox Code Playgroud)

斯威夫特3

extension UIViewController {

    /**
     *  Height of status bar + navigation bar (if navigation bar exist)
     */

    var topbarHeight: CGFloat {
        return UIApplication.shared.statusBarFrame.size.height +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • Swift 4 的答案为我返回了 0 高度。 (3认同)

Kin*_*ard 59

Swift版本:

let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height
Run Code Online (Sandbox Code Playgroud)


Lal*_*hna 12

iOS 14

对我来说,view.window在 iOS 14 上为 null。

extension UIViewController {
    var topBarHeight: CGFloat {
        var top = self.navigationController?.navigationBar.frame.height ?? 0.0
        if #available(iOS 13.0, *) {
            top += UIApplication.shared.windows.first?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
        } else {
            top += UIApplication.shared.statusBarFrame.height
        }
        return top
    }
}
Run Code Online (Sandbox Code Playgroud)


Hit*_*esh 9

支持 iOS 13 及以下:

extension UIViewController {

    var topbarHeight: CGFloat {
        if #available(iOS 13.0, *) {
            return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
                (self.navigationController?.navigationBar.frame.height ?? 0.0)
        } else {
            let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
            return topBarHeight
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 8

斯威夫特 5

如果要获取导航栏高度,请使用maxY考虑 safeArea 大小的属性,如下所示:

 let height = navigationController?.navigationBar.frame.maxY  
Run Code Online (Sandbox Code Playgroud)


Kea*_*eaz 6

你试过这个吗?

let barHeight = self.navigationController?.navigationBar.frame.height ?? 0
Run Code Online (Sandbox Code Playgroud)


小智 5

UIImage*image = [UIImage imageNamed:@"logo"];

float targetHeight = self.navigationController.navigationBar.frame.size.height;
float logoRatio = image.size.width / image.size.height;
float targetWidth = targetHeight * logoRatio;

UIImageView*logoView = [[UIImageView alloc] initWithImage:image];
// X or Y position can not be manipulated because autolayout handles positions.
//[logoView setFrame:CGRectMake((self.navigationController.navigationBar.frame.size.width - targetWidth) / 2 , (self.navigationController.navigationBar.frame.size.height - targetHeight) / 2 , targetWidth, targetHeight)];
[logoView setFrame:CGRectMake(0, 0, targetWidth, targetHeight)];
self.navigationItem.titleView = logoView;

// How much you pull out the strings and struts, with autolayout, your image will fill the width on navigation bar. So setting only height and content mode is enough/
[logoView setContentMode:UIViewContentModeScaleAspectFit];

/* Autolayout constraints also can not be manipulated since navigation bar has  immutable constraints
self.navigationItem.titleView.translatesAutoresizingMaskIntoConstraints = false;

NSDictionary*metricsArray = @{@"width":[NSNumber numberWithFloat:targetWidth],@"height":[NSNumber numberWithFloat:targetHeight],@"margin":[NSNumber numberWithFloat:20]};
NSDictionary*viewsArray = @{@"titleView":self.navigationItem.titleView};

[self.navigationItem.titleView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>margin=)-H:[titleView(width)]-(>margin=)-|" options:NSLayoutFormatAlignAllCenterX metrics:metricsArray views:viewsArray]];
[self.navigationItem.titleView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[titleView(height)]" options:0 metrics:metricsArray views:viewsArray]];

NSLog(@"%f", self.navigationItem.titleView.width );
*/
Run Code Online (Sandbox Code Playgroud)

所以我们真正需要的是

UIImage*image = [UIImage imageNamed:@"logo"];
UIImageView*logoView = [[UIImageView alloc] initWithImage:image];
float targetHeight = self.navigationController.navigationBar.frame.size.height;
[logoView setFrame:CGRectMake(0, 0, 0, targetHeight)];
[logoView setContentMode:UIViewContentModeScaleAspectFit];

self.navigationItem.titleView = logoView;
Run Code Online (Sandbox Code Playgroud)


Cod*_*ess 5

方便的 Swift 4 扩展,以防对其他人有帮助。即使当前视图控制器不显示导航栏也可以工作。

import UIKit

extension UINavigationController {
  static public func navBarHeight() -> CGFloat {
    let nVc = UINavigationController(rootViewController: UIViewController(nibName: nil, bundle: nil))
    let navBarHeight = nVc.navigationBar.frame.size.height
    return navBarHeight
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

UINavigationController.navBarHeight()
Run Code Online (Sandbox Code Playgroud)


小智 2

灯泡开始亮起来。不幸的是,我还没有找到纠正该问题的统一方法,如下所述。

\n\n

我相信我的整个问题集中在我的 autoresizingMasks 上。我得出结论的原因是,无论有没有 UIWebView,都存在相同的症状。这个症状是肖像的一切都是桃色的。对于横向,最底部的 UIButton 在 TabBar 后面弹出。

\n\n

例如,在一个 UIView 上,我从上到下:

\n\n

UIView \xe2\x80\x93 两个弹簧都设置(默认情况)并且没有支柱

\n\n

UIScrollView -\n如果我设置两个弹簧,并清除其他所有内容(如 UIView),则 UIButton 会侵入紧邻其上方的对象。\n如果我清除所有内容,则 UIButton 没问题,但最顶部的内容会隐藏在 StatusBar 后面\n仅设置顶部支柱,UIButton 将在选项卡栏后面弹出。

\n\n

UILabel 和 UIImage垂直排列 \xe2\x80\x93 顶部支柱设置,其他地方都很灵活

\n\n

只是为了让少数拥有 UIWebView 的人完成图片:

\n\n

UIWebView -\nStruts:上、左、右\nSprings:两者

\n\n

UIButton \xe2\x80\x93 没有设置,即到处灵活

\n\n

虽然我的灯泡很暗,但似乎还有希望。

\n