ios 以编程方式获取导航栏的高度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7312059/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Programmatically get height of navigation bar
提问by Sum
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
.
我知道更多视图控制器(导航栏)的存在会按其高度向下推 UIView。我也知道这个高度 = 44px。我还发现这种下推保持了[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?
或者,更短的版本,我如何确定我的 UIView 是否在顶部显示导航栏?
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.
我相信我的整个问题都集中在我的 autoresizingMasks 上。我得出的结论是,无论是否有 UIWebView,都存在相同的症状。这种症状是肖像的一切都是桃色的。对于横向,最底部的 UIButton 会在 TabBar 后面弹出。
For example, on one UIView, I have, from top to bottom:
例如,在一个 UIView 上,我从上到下有:
UIView – both springs set (default case) and no struts
UIView – 设置了弹簧(默认情况)并且没有支柱
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.
UIScrollView - 如果我设置了两个弹簧,并清除了其他所有内容(如 UIView),则 UIButton 会侵入其正上方的对象。如果我清除了所有内容,那么 UIButton 就可以了,但是最顶部的东西隐藏在 StatusBar 后面 设置仅顶部支柱,UIButton 在 Tab Bar 后面弹出。
UILabel and UIImage next vertically – top strut set, flexible everywhere else
UILabel 和 UIImage 接下来垂直 – 顶部支柱设置,其他地方灵活
Just to complete the picture for the few that have a UIWebView:
只是为了完成少数拥有 UIWebView 的图片:
UIWebView - Struts: top, left, right Springs: both
UIWebView - Struts:上、左、右 Springs:两者
UIButton – nothing set, i.e., flexible everywhere
UIButton – 什么都没有设置,即,处处灵活
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.
1) 每个 UIViewController(一个 TabBar 应用程序)都有一个 UIImage、一些文本和顶部的任何内容。另一个共同点是底部的 UIButton。在一些 UIViewControllers 上,我在 UIButton 上方有一个 UIWebView。
So, UIImage, text etc. UIWebView (on SOME) UIButton
所以,UIImage, text 等 UIWebView (on SOME) UIButton
Surrounding all the above is a UIScrollView.
围绕上述所有内容的是一个 UIScrollView。
2) For those that have a UIWebView, its autoresizingMask looks like:
2) 对于那些有 UIWebView 的,它的 autoresizingMask 看起来像:
—
|
—
^
|
|
|—| ←----→ |—| | | V The UIButton's mask has nothing set, i.e., flexible everywhere
|—| ←----→ |—| | | V UIButton 的 mask 没有设置,即随处灵活
Within my -viewDidLoad, I call my -repositionSubViews within which I do the following:
在我的 -viewDidLoad 中,我调用了我的 -repositionSubViews,在其中执行以下操作:
If there is no UIWebView, I do nothing except center the UIButton that I placed with IB.
如果没有 UIWebView,除了将放置在 IB 中的 UIButton 居中之外,我什么都不做。
If I do have a UIWebView, then I determine its *content*Height and set its frame to enclose the entire content.
如果我确实有一个 UIWebView,那么我确定它的 *content*Height 并设置它的框架以包含整个内容。
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.
一旦我这样做了,然后我以编程方式将 UIButton 向下推,使其最终放置在 UIWebView 下方。
Everything works, until I rotate it from Portrait to Landscape.
一切正常,直到我将它从纵向旋转到横向。
I call my -repositionSubViews within my -didRotateFromInterfaceOrientation.
我在我的 -didRotateFromInterfaceOrientation 中调用了我的 -repositionSubViews。
Why does the content height of my UIWebView not change with rotation?.
为什么我的 UIWebView 的内容高度不会随着旋转而改变?。
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.
从纵向到横向,内容宽度应该扩大,内容高度应该缩小。它在视觉上表现得像它应该的那样,但不是根据我的 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.
无论如何,无论有没有 UIWebView,我谈到的按钮在横向模式下都会在 TabBar 下方移动,但不会向上滚动以查看。当我“大力”滚动时,我看到它在 TabBar 后面,但随后它“退回”到 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.
最重要的是,这最后一个是我询问 TabBar 和 NavigationBar 高度的原因,因为 TabBar 将自身置于 UIView 的底部,而 NavigationBar 将 UIView 向下推。
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.
在没有 UIWebView 的情况下,我保留了 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.
使用 UIWebView,我将 UIWebView 的 frame.height 增加到它的 contentHeight 并向上调整围绕所有子视图的周围 UIScrollView 的高度。
Well there you have it.
那么你有它。
采纳答案by mojtaba al moussawi
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.
我相信我的整个问题都集中在我的 autoresizingMasks 上。我得出的结论是,无论是否有 UIWebView,都存在相同的症状。这种症状是肖像的一切都是桃色的。对于横向,最底部的 UIButton 会在 TabBar 后面弹出。
For example, on one UIView, I have, from top to bottom:
例如,在一个 UIView 上,我从上到下有:
UIView– both springs set (default case) and no struts
UIView– 设置了弹簧(默认情况)并且没有支柱
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.
UIScrollView- 如果我设置了两个弹簧,并清除了其他所有内容(如 UIView),则 UIButton 会侵入其正上方的对象。如果我清除了所有内容,那么 UIButton 就可以了,但是最顶部的东西隐藏在 StatusBar 后面 设置仅顶部支柱,UIButton 在 Tab Bar 后面弹出。
UILabel and UIImagenext vertically – top strut set, flexible everywhere else
UILabel 和 UIImage接下来垂直 – 顶部支柱设置,其他地方灵活
Just to complete the picture for the few that have a UIWebView:
只是为了完成少数拥有 UIWebView 的图片:
UIWebView- Struts: top, left, right Springs: both
UIWebView- Struts:上、左、右 Springs:两者
UIButton– nothing set, i.e., flexible everywhere
UIButton– 什么都没有设置,即,处处灵活
Although my light bulb is dim, there appears to be hope.
虽然我的灯泡很暗,但似乎还有希望。
回答by Sum
Do something like this ?
做这样的事情?
NSLog(@"Navframe Height=%f",
self.navigationController.navigationBar.frame.size.height);
The swift version is located here
快速版本位于此处
UPDATE
更新
iOS 13
iOS 13
As the statusBarFrame
was deprecated in iOS13
you can use this:
由于statusBarFrame
已弃用,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)
}
}
回答by Krunal
With iPhone-X, height of top bar (navigation bar + status bar) is changed (increased).
使用 iPhone-X,顶部栏(导航栏 + 状态栏)的高度发生了变化(增加)。
Try this if you want exact height of top bar (both navigation bar + status bar):
如果您想要顶部栏的确切高度(导航栏 + 状态栏),请尝试此操作:
UPDATE
更新
iOS 13
iOS 13
As the statusBarFrame
was deprecated in iOS13
you can use this:
由于statusBarFrame
已弃用,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
目标-C
CGFloat topbarHeight = ([UIApplication sharedApplication].statusBarFrame.size.height +
(self.navigationController.navigationBar.frame.size.height ?: 0.0));
Swift 4
斯威夫特 4
let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)
For ease, try this UIViewController extension
为方便起见,试试这个 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
斯威夫特 3
let topBarHeight = UIApplication.sharedApplication().statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)
回答by King-Wizard
Swiftversion:
迅捷版:
let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height
回答by Keaz
Did you try this?
你试过这个吗?
let barHeight = self.navigationController?.navigationBar.frame.height ?? 0
回答by COVID19
Support iOS 13 and Below:
支持 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
}
}
}
回答by ironik sütla?
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;
回答by Stephen Liu
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.
我的应用程序有几个视图需要在 UI 中使用自定义导航栏来实现外观和感觉,但没有导航控制器。并且该应用程序需要支持iOS 11之前的iOS版本,因此无法使用方便的安全区域布局指南,我必须通过编程调整导航栏的位置和高度。
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...
我直接将导航栏附加到它的超级视图,跳过了上面提到的安全区域布局指南。状态栏高度可以很容易地从 UIApplication 中检索出来,但是默认的导航栏高度真的很麻烦……
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:
它让我震惊了将近半夜,进行了多次搜索和测试,直到我终于从另一篇文章中得到了提示(尽管对我不起作用),您实际上可以从 UIView.sizeThatFits() 获取高度,就像这样:
- (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!
最后,一个完美的导航栏看起来与内置导航栏一模一样!
回答by mojtaba al moussawi
If you want to get the navigationBar
height only, it's simple:
如果你只想得到navigationBar
高度,这很简单:
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.
但是,如果您需要 iPhone 的顶级高度,则无需获取navigationBar
高度并将其添加到statusBar
高度,您可以简单地调用safeAreaInsets
这就是存在的原因。
self.view.safeAreaInsets.top
回答by Sum
Here is the beginning of my response to your update:
以下是我对您更新的回复的开头:
Why does the content height of my UIWebView not change with rotation?.
为什么我的 UIWebView 的内容高度不会随着旋转而改变?。
Could it be that because your auto resize doesn't have the autoresizingMask for all directions?
可能是因为您的自动调整大小没有针对所有方向的 autoresizingMask 吗?
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
在我回来之前的另一个建议,您能否根据需要使用工具栏。它更简单一点,总是在底部,自动旋转/位置。你可以随意隐藏/显示它等等。有点像这样: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)
另一个想法,您是否可以检测到您从哪个方向旋转,然后以编程方式放置按钮以调整选项卡栏。(这可以通过代码实现)