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

发布于 2024-12-02 23:06:42 字数 2457 浏览 1 评论 0原文

我知道更多视图控制器(导航栏)的存在将 UIView 的高度推低。我也知道这个高度=44px。我还发现这个下推维护了[self.view].frame.origin.y = 0

那么,除了将其设置为常量之外,如何确定该导航栏的高度呢?

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


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

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

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

UIView – 两个弹簧均已设置(默认情况)并且没有支柱

UIScrollView – 如果我设置两个弹簧,并清除其他所有内容(如 UIView),则 UIButton 会侵入位于其正上方的物体上。如果我清除所有内容,那么 UIButton 就可以了,但是最顶部的东西隐藏在 StatusBar 后面 仅设置顶部支柱,UIButton 会在选项卡栏后面弹出。

UILabel 和 UIImage 垂直排列 – 顶部支柱设置,在其他地方都灵活

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

UIWebView - Struts:顶部、左侧、右侧 Springs:两个

UIButton – 没有设置,即到处都灵活

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


请耐心等待,因为我需要比简短回复评论更多的空间。

感谢您尝试了解我真正想要的东西......所以就这样。

1)每个UIViewController(一个TabBar应用程序)都有一个UIImage,一些文本以及顶部的任何内容。另一个共同点是底部有一个 UIButton。在某些 UIViewController 上,我在 UIButton 上方有一个 UIWebView。

因此,UIImage、文本等 UIWebView(在某些方面) UIButton

围绕以上所有内容的是 UIScrollView。

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

   —
   |
   —

   ^
   |
   |

|—| ←----→ |—| | | 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)]

一旦我这样做了,我就会以编程方式将 UIButton 向下推,使其最终放置在 UIWebView 下方。

一切正常,直到我将其从纵向旋转为横向。

我在 -didRotateFromInterfaceOrientation 中调用我的 -repositionSubViews。

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

从纵向到横向,内容宽度应扩大,内容高度应缩小。它在视觉上是正常的,但不是根据我的 NSLog 的。

不管怎样,无论有没有 UIWebView,我讨论过的按钮在横向模式下都会移动到 TabBar 下方,但不会向上滚动看到。当我“大力”滚动时,我看到它位于 TabBar 后面,但随后它“回落”到 TabBar 后面。

最后,这就是我询问 TabBar 和 NavigationBar 高度的原因,因为 TabBar 位于 UIView 的底部,而 NavigationBar 将 UIView 向下推。

现在,我要在这里添加一两条评论,因为它们在早些时候是没有意义的。

由于没有 UIWebView,我将一切保留为 IB 所看到的样子。

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

好吧,你已经有了。

I know that the presence of the more view controller (navigation bar) pushes down the UIView by its height. I also know that this height = 44px. I have also discovered that this push down maintains the [self.view].frame.origin.y = 0.

So how do I determine the height of this navigation bar, other than just setting it to a constant?

Or, shorter version, how do I determine that my UIView is showing with the navigation bar on top?


The light bulb started to come on. Unfortunately, I have not discovered a uniform way to correct the problem, as described below.

I believe that my whole problem centers on my autoresizingMasks. And the reason I have concluded that is the same symptoms exist, with or without a UIWebView. And that symptom is that everything is peachy for Portrait. For Landscape, the bottom-most UIButton pops down behind the TabBar.

For example, on one UIView, I have, from top to bottom:

UIView – both springs set (default case) and no struts

UIScrollView - If I set the two springs, and clear everything else (like the UIView), then the UIButton intrudes on the object immediately above it. If I clear everything, then UIButton is OK, but the stuff at the very top hides behind the StatusBar Setting only the top strut, the UIButton pops down behind the Tab Bar.

UILabel and UIImage next vertically – top strut set, flexible everywhere else

Just to complete the picture for the few that have a UIWebView:

UIWebView - Struts: top, left, right Springs: both

UIButton – nothing set, i.e., flexible everywhere

Although my light bulb is dim, there appears to be hope.


Please bear with me because I needed more room than that provided for a short reply comment.

Thanks for trying to understand what I am really fishing for ... so here goes.

1) Each UIViewController (a TabBar app) has a UIImage, some text and whatever on top. Another common denominator is a UIButton on the bottom. On some of the UIViewControllers I have a UIWebView above the UIButton.

So, UIImage, text etc. UIWebView (on SOME) UIButton

Surrounding all the above is a UIScrollView.

2) For those that have a UIWebView, its autoresizingMask looks like:

   —
   |
   —

   ^
   |
   |

|—| ←----→ |—|
|
|
V
The UIButton's mask has nothing set, i.e., flexible everywhere

Within my -viewDidLoad, I call my -repositionSubViews within which I do the following:

If there is no UIWebView, I do nothing except center the UIButton that I placed with IB.

If I do have a UIWebView, then I determine its *content*Height and set its frame to enclose the entire content.

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

Once I do that, then I programmatically push the UIButton down so that it ends up placed below the UIWebView.

Everything works, until I rotate it from Portrait to Landscape.

I call my -repositionSubViews within my -didRotateFromInterfaceOrientation.

Why does the content height of my UIWebView not change with rotation?.

From Portrait to Landscape, the content width should expand and the content height should shrink. It does visually as it should, but not according to my NSLog.

Anyway, with or without a UIWebView, the button I've talked about moves below the TabBar when in Landscape mode but it will not scroll up to be seen. I see it behind the TabBar when I scroll "vigorously", but then it "falls back" behind the TabBar.

Bottom line, this last is the reason I've asked about the height of the TabBar and the NavigationBar because the TabBar plants itself at the bottom of the UIView and the NavigationBar pushes the UIView down.

Now, I'm going to add a comment or two here because they wouldn't have made sense earlier.

With no UIWebView, I leave everything as is as seen by IB.

With a UIWebView, I increase the UIWebView's frame.height to its contentHeight and also adjust upward the height of the surrounding UIScrollView that surrounds all the sub-views.

Well there you have it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

美羊羊 2024-12-09 23:06:43

对于iPhone-X,顶部栏(导航栏+状态栏)的高度发生变化(增加)。

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

更新

iOS 13

作为statusBarFrame< /code> 在 iOS13 中已弃用,您可以使用:

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

Objective-C

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

Swift 4

let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
        (self.navigationController?.navigationBar.frame.height ?? 0.0)

为了方便起见,请尝试这个 UIViewController 扩展

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

Swift 3

let topBarHeight = UIApplication.sharedApplication().statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)

With iPhone-X, height of top bar (navigation bar + status bar) is changed (increased).

Try this if you want exact height of top bar (both navigation bar + status bar):

UPDATE

iOS 13

As the statusBarFrame was deprecated in iOS13 you can use this:

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

Objective-C

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

Swift 4

let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
        (self.navigationController?.navigationBar.frame.height ?? 0.0)

For ease, try this UIViewController extension

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

Swift 3

let topBarHeight = UIApplication.sharedApplication().statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)

花开浅夏 2024-12-09 23:06:43

Swift 版本:

let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height

Swift version:

let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height
水染的天色ゝ 2024-12-09 23:06:43

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

iOS 14

For me, view.window is null on iOS 14.

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
    }
}
暖阳 2024-12-09 23:06:43

Swift 5

如果您想获取导航栏高度,请使用同时考虑安全区域大小的 maxY 属性,如下所示:

 let height = navigationController?.navigationBar.frame.maxY  

Swift 5

If you want to get the navigation bar height, use the maxY property that considers the safeArea size as well, like this:

 let height = navigationController?.navigationBar.frame.maxY  
活泼老夫 2024-12-09 23:06:43

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

Support iOS 13 and Below:

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
        }
    }
}
梅倚清风 2024-12-09 23:06:43

你尝试过这个吗?

let barHeight = self.navigationController?.navigationBar.frame.height ?? 0

Did you try this?

let barHeight = self.navigationController?.navigationBar.frame.height ?? 0
过期情话 2024-12-09 23:06:43
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 );
*/

所以我们真正需要的是

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;
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 );
*/

So all we actually need is

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;
灼疼热情 2024-12-09 23:06:43

方便的 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
  }
}

用法:

UINavigationController.navBarHeight()

Handy Swift 4 extension, in case it's helpful to someone else. Works even if the current view controller does not display a navigation bar.

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

Usage:

UINavigationController.navBarHeight()
彡翼 2024-12-09 23:06:43

我的应用程序有几个视图,需要在 UI 中自定义导航栏以进行外观和显示。感觉,但是没有导航控制器。并且该应用程序需要支持iOS 11之前的iOS版本,因此无法使用方便的安全区域布局指南,我必须以编程方式调整导航栏的位置和高度。

我直接将导航栏附加到其超级视图,跳过了上面提到的安全区域布局指南。而且状态栏的高度可以很方便地从UIApplication中获取,但是默认的导航栏高度实在是太蛋疼了……

折腾了我半个晚上,进行了多次搜索和测试,终于得到了提示从另一篇文章(虽然对我不起作用),您实际上可以从 UIView.sizeThatFits() 获取高度,如下所示:

- (void)viewWillLayoutSubviews {
    self.topBarHeightConstraint.constant = [UIApplication sharedApplication].statusBarFrame.size.height;
    self.navBarHeightConstraint.constant = [self.navigationBar sizeThatFits:CGSizeZero].height;

    [super viewWillLayoutSubviews];    
}

最后,一个完美的导航栏看起来与内置导航栏完全相同!

My application has a couple views that required a customized navigation bar in the UI for look & feel, however without navigation controller. And the application is required to support iOS version prior to iOS 11, so the handy safe area layout guide could not be used, and I have to adjust the position and height of navigation bar programmatically.

I attached the Navigation Bar to its superview directly, skipping the safe area layout guide as mentioned above. And the status bar height could be retrieved from UIApplication easily, but the default navigation bar height is really a pain-ass...

It struck me for almost half a night, with a number of searching and testing, until I finally got the hint from another post (not working to me though), that you could actually get the height from UIView.sizeThatFits(), like this:

- (void)viewWillLayoutSubviews {
    self.topBarHeightConstraint.constant = [UIApplication sharedApplication].statusBarFrame.size.height;
    self.navBarHeightConstraint.constant = [self.navigationBar sizeThatFits:CGSizeZero].height;

    [super viewWillLayoutSubviews];    
}

Finally, a perfect navigation bar looking exactly the same as the built-in one!

念﹏祤嫣 2024-12-09 23:06:43

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

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

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

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

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

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

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

UIWebView -
支柱:上、左、右
Springs:都是

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

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

The light bulb started to come on. Unfortunately, I have not discovered a uniform way to correct the problem, as described below.

I believe that my whole problem centers on my autoresizingMasks. And the reason I have concluded that is the same symptoms exist, with or without a UIWebView. And that symptom is that everything is peachy for Portrait. For Landscape, the bottom-most UIButton pops down behind the TabBar.

For example, on one UIView, I have, from top to bottom:

UIView – both springs set (default case) and no struts

UIScrollView -
If I set the two springs, and clear everything else (like the UIView), then the UIButton intrudes on the object immediately above it.
If I clear everything, then UIButton is OK, but the stuff at the very top hides behind the StatusBar
Setting only the top strut, the UIButton pops down behind the Tab Bar.

UILabel and UIImage next vertically – top strut set, flexible everywhere else

Just to complete the picture for the few that have a UIWebView:

UIWebView -
Struts: top, left, right
Springs: both

UIButton – nothing set, i.e., flexible everywhere

Although my light bulb is dim, there appears to be hope.

锦上情书 2024-12-09 23:06:43

以下是我对您的更新的回复的开头:

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

是否是因为您的自动调整大小没有所有方向的 autoresizingMask ?

在我回来之前,另一个建议是,您可以使用工具栏来满足您的需求。它更简单一点,总是在底部,自动旋转/位置。您可以随意隐藏/显示它等。有点像这样:http://cdn.artoftheiphone.com/wp-content/uploads/2009/01/yellow-pages-iphone-app-2.jpg

您可能已经看过该选项,但只是将其扔掉。

另一个想法是,您是否可以检测到旋转的方向,然后以编程方式放置按钮来调整选项卡栏。 (这可以通过代码实现)

Here is the beginning of my response to your update:

Why does the content height of my UIWebView not change with rotation?.

Could it be that because your auto resize doesn't have the autoresizingMask for all directions?

Another suggestion before I come back for this, could you use a toolbar for your needs. It's a little simpler, will always be on the bottom, auto-rotates/positions. You can hide/show it at will etc. Kind of like this: http://cdn.artoftheiphone.com/wp-content/uploads/2009/01/yellow-pages-iphone-app-2.jpg

You may have looked at that option, but just throwing it out there.

Another idea, could you possibly detect what orientation you are rotating from, and just place the button programmatically to adjust for the tab bar. (This is possible with code)

挖个坑埋了你 2024-12-09 23:06:43

我使用过:

let originY: CGFloat = self.navigationController!.navigationBar.frame.maxY

如果你想获得导航栏高度及其 Y 原点,效果很好。

I have used:

let originY: CGFloat = self.navigationController!.navigationBar.frame.maxY

Working great if you want to get the navigation bar height AND its Y origin.

时光沙漏 2024-12-09 23:06:43

如果您只想获取 navigationBar 高度,很简单:

extension UIViewController{
   var navigationBarHeight: CGFloat {
       return self.navigationController?.navigationBar.frame.height ?? 0.0
   }
}

但是,如果您需要 iPhone 顶部的高度,则不需要获取 navigationBar 高度,添加 statusBar 高度,您可以简单地调用 safeAreaInsets 这就是存在的原因。

self.view.safeAreaInsets.top

If you want to get the navigationBar height only, it's simple:

extension UIViewController{
   var navigationBarHeight: CGFloat {
       return self.navigationController?.navigationBar.frame.height ?? 0.0
   }
}

However, if you need the height of top notch of iPhone you don't need to get the navigationBar height and add to it the statusBar height, you can simply call safeAreaInsets that's why exist.

self.view.safeAreaInsets.top
不爱素颜 2024-12-09 23:06:43

Swift:以编程方式在导航栏下方添加 Web 视图

从 iOS11 开始,将视图定位在导航栏下方的关键是使用

Apple 文档中的 safeAreaLayoutGuide (链接):

布局指南,表示视图中未被栏和其他内容遮挡的部分。

因此,在代码中,我将使用 view.safeAreaLayoutGuide.topAnchor 放置顶部约束

再次,整个事情将是例如:

import WebKit

class SettingsViewController: UIViewController {
let webView = WKWebView()
let url = URL(string: "https://www.apple.com")

override func viewDidLoad() {
        super.viewDidLoad()
        configureWebView()
}

override func viewWillAppear(_ animated: Bool) {
        follow(url: url)
}

func follow(url: URL?) {
        if let url = url {
            let request = URLRequest(url: url)
            webView.load(request)
    }
}

func configureWebView() {
        view.addSubview(webView)
        webView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
}
}

Swift : programmatically adding a web view right under the navigation bar

From iOS11 the key to position the view below the navigation bar is to use safeAreaLayoutGuide

From the Apple docs (link):

The layout guide representing the portion of your view that is unobscured by bars and other content.

So in code I will put the top constraint using view.safeAreaLayoutGuide.topAnchor

Again the whole thing will be for example:

import WebKit

class SettingsViewController: UIViewController {
let webView = WKWebView()
let url = URL(string: "https://www.apple.com")

override func viewDidLoad() {
        super.viewDidLoad()
        configureWebView()
}

override func viewWillAppear(_ animated: Bool) {
        follow(url: url)
}

func follow(url: URL?) {
        if let url = url {
            let request = URLRequest(url: url)
            webView.load(request)
    }
}

func configureWebView() {
        view.addSubview(webView)
        webView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
}
}
高速公鹿 2024-12-09 23:06:42

做这样的事情吗?

    NSLog(@"Navframe Height=%f",
        self.navigationController.navigationBar.frame.size.height);

swift 版本位于此处


更新

iOS 13

由于 statusBarFrameiOS13 你可以使用这个:

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

Do something like this ?

    NSLog(@"Navframe Height=%f",
        self.navigationController.navigationBar.frame.size.height);

The swift version is located here


UPDATE

iOS 13

As the statusBarFrame was deprecated in iOS13 you can use this:

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)
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文