ios 有没有办法在不使用 UINavigationController 的情况下更改 Storyboard 中 UINavigationBar 的高度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20439167/
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
Is there a way to change the height of a UINavigationBar in Storyboard without using a UINavigationController?
提问by Sti
I want to use a custom UINavigationBar
in one of my views, which is not a part of any UINavigationController
-hierarchy. When I drag a UINavigationBar
into Storyboard, it shows like this:
我想UINavigationBar
在我的一个视图中使用自定义,它不是任何UINavigationController
层次结构的一部分。当我将 aUINavigationBar
拖入 Storyboard 时,它显示如下:
This bar is 44px, which would be enough if the status bar wouldn't share this space. Because iOS7 lets us use the entire screen, including the space for the status bar, the UINavigationBar
should be 64px tall, not 44px.
这个栏是 44px,如果状态栏不共享这个空间就足够了。因为 iOS7 允许我们使用整个屏幕,包括状态栏的空间,所以UINavigationBar
应该是 64px 高,而不是 44px。
If I connect the view to a UINavigationController
's hierarchy, then it shows correct:
如果我将视图连接到 aUINavigationController
的层次结构,则它显示正确:
I read somewhere that ifthe UINavigationBar
has the property barPosition:
set to UIBarPositionTopAttached
, then the bar would be 64px. This is, however, a readonly
-property.
我读的地方,如果在UINavigationBar
拥有的财产barPosition:
设置为UIBarPositionTopAttached
,那么酒吧是64PX。然而,这是一个readonly
- 属性。
My search results have only shown something I consider a "work-around". By adding a useless UINavigationController
before this UIViewController
, I can pretend to have a hierarchy, and it will add the UINavigationBar
with 64px automatically.
我的搜索结果只显示了我认为“变通”的东西。通过UINavigationController
在这之前添加一个无用的UIViewController
,我可以假装有一个层次结构,它会UINavigationBar
自动添加64px 。
Is there reallyno way to have a 'rogue'(without the help of a navigation controller) UINavigationBar
that covers 64px?
If that is the case, is there any valid reasons as to why?
有没有真的没有办法有一个“流氓”(没有导航控制器的帮助下)UINavigationBar
,涵盖64PX?如果是这种情况,是否有任何正当理由说明原因?
(I'm not saying the UINavigationBar
should be 64px by default, but there should be an option for it in the inspector)
(我不是说UINavigationBar
默认情况下应该是 64px,但在检查器中应该有一个选项)
(I also see people answering with programmatic ways to solve this. Even though these answers works, I'd still have to designthe storyboard with that in mind (a gap). What I want to know is if it's possible to set this in storyboard, or rather, why isn't it allowed?)
(我也看到人们用编程方式来解决这个问题。即使这些答案有效,我仍然必须考虑到这一点(差距)来设计故事板。我想知道是否可以将其设置为故事板,或者更确切地说,为什么不允许?)
采纳答案by user3269713
You can set the property barPosition
to UIBarPositionTopAttached
another way!
您可以将属性设置barPosition
为UIBarPositionTopAttached
另一种方式!
- Add a delegate to your UINavigationBar.
Implement
-positionForBar:
in the delegate class:- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; }
- 将委托添加到您的 UINavigationBar。
落实
-positionForBar:
在委托类:- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; }
Your navigation bar's top must also be anchored to the Top Layout Guide.
您的导航栏的顶部也必须锚定到顶部布局指南。
回答by Lyndsey Scott
You can change the nav bar height programmatically:
您可以以编程方式更改导航栏高度:
[navBar setFrame:CGRectMake(0, 0, 320, 64)];
Edit: As I wrote in the comments, you may have to put this line in viewDidLayoutSubviews
to circumvent autolayout.
编辑:正如我在评论中所写,您可能必须将此行放入viewDidLayoutSubviews
以规避自动布局。
回答by joerick
You can set it to attach to the top of the view using 'User Defined Runtime Attributes' in 'Identity Inspector' in Interface Builder. Set the barPosition
property.
您可以使用 Interface Builder 中“Identity Inspector”中的“User Defined Runtime Attributes”将其设置为附加到视图的顶部。设置barPosition
属性。
Here's the documentation for the barPosition
property: https://developer.apple.com/library/ios/documentation/uikit/reference/UIBarPositioning_Protocol/Reference/Reference.html
这是该barPosition
属性的文档:https: //developer.apple.com/library/ios/documentation/uikit/reference/UIBarPositioning_Protocol/Reference/Reference.html
回答by barndog
There is a way to accomplish this WITHOUT using a UINavigationController
or setting it programmatically. Just set a height constraint on the navigation bar to whatever you want, 64 in this instance.
有一种方法可以在不使用 aUINavigationController
或以编程方式设置的情况下完成此操作。只需将导航栏上的高度限制设置为您想要的任何值,在本例中为 64。
You can accomplish the same thing programmatically as such:
您可以通过编程方式完成同样的事情:
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:navigationBar attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1 constant:64.0f]];
EDIT:
编辑:
As @nerdist-colony pointed out, when working with Autolayout it's always been to set translatesAutoresizingMaskIntoConstraints
to NO
otherwise there may be conflicts in the constraints.
正如@nerdist-colony 指出的那样,在使用 Autolayout 时,总是设置translatesAutoresizingMaskIntoConstraints
为NO
否则约束中可能会出现冲突。
回答by kketch
I'm using a standalone UINavigationBar too and I encountered the same issue, and I found there is two ways fixing this properly.
我也在使用独立的 UINavigationBar,我遇到了同样的问题,我发现有两种方法可以正确解决这个问题。
I fixed it using constraints, and a parent UIView. I set this UIView in the storyboard as the parent view of my UINavigationBar with a {0, 0, 320, 64} frame. You can add a constraint or a set of constraints forcing the UINavigationBar to have the desired size. And given that your parent UIView has the correct frame in your storyboard, you can layout as usual your other views in your storyboard.
我使用约束和父 UIView 修复了它。我在情节提要中将此 UIView 设置为带有 {0, 0, 320, 64} 框架的 UINavigationBar 的父视图。您可以添加一个或一组约束来强制 UINavigationBar 具有所需的大小。鉴于您的父 UIView 在您的故事板中有正确的框架,您可以像往常一样在故事板中布置其他视图。
Now if autolayout is disabled you can change the bar height programmatically as described in Lindsey's answer.
-(void)viewDidLayoutSubviews
seems to be a good spot to do it.
现在,如果禁用自动布局,您可以按照 Lindsey 的回答中所述以编程方式更改条形高度。
-(void)viewDidLayoutSubviews
似乎是做这件事的好地方。
回答by mrcuongth
If you using Autolayout, you can set Height of UINavigationBar's constraint to 64 or event more.
如果您使用自动布局,您可以将 UINavigationBar 约束的高度设置为 64 或更多。
回答by leanne
I've written a blog post detailing how to do this with minimal code intervention. Your bar will show a gap in the storyboard, but it will work fine on the device. In short, the steps are:
我写了一篇博客文章,详细介绍了如何以最少的代码干预来做到这一点。您的条形图会在情节提要中显示一个间隙,但它在设备上可以正常工作。简而言之,步骤是:
1) Add the navigation bar to the view controller in the storyboard.
1) 将导航栏添加到故事板中的视图控制器。
2) Set the constraints for the navigation bar in the storyboard:
- Navigation Bar.Top = Top Layout Guide.Bottom
- Navigation Bar.Leading = Superview.Leading
- Navigation Bar.Trailing = Superview.Trailing
2)在storyboard中设置导航栏的约束条件:
- Navigation Bar.Top = Top Layout Guide.Bottom
- Navigation Bar.Leading = Superview.Leading
- Navigation Bar.Trailing = Superview.Trailing
3) Connect the storyboard's navigation bar to its view controller as an @IBOutlet.
3) 将故事板的导航栏作为@IBOutlet 连接到其视图控制器。
4) In the view controller's class, add a UINavigationBarDelegate protocol to the class declaration.
4) 在视图控制器的类中,在类声明中添加一个 UINavigationBarDelegate 协议。
5) In the view controller's viewDidLoad method, set the navigation bar's delegate to self.
5) 在视图控制器的 viewDidLoad 方法中,将导航栏的委托设置为 self。
6) In the view controller, add the bar positioning delegate's positionForBar method. Return the UIBarPosition representing TopAttached. (Note: UINavigationBarDelegate inherits this method from UIBarPositioningDelegate.)
6) 在视图控制器中,添加条形定位委托的 positionForBar 方法。返回代表 TopAttached 的 UIBarPosition。(注意:UINavigationBarDelegate 从 UIBarPositioningDelegate 继承了这个方法。)
The full post with GIF images is here:
Easily use a Navigation Bar without a corresponding Navigation Controller
带有 GIF 图像的完整帖子在这里:
轻松使用没有相应导航控制器的导航栏
These steps work as of Swift 2.1/Xcode 7.2
这些步骤适用于 Swift 2.1/Xcode 7.2
回答by FreitDev
In Swift 3 using the main storyboard you can use constraints to change the height and make it work. This was the way that I found is easy to implement.
在使用主故事板的 Swift 3 中,您可以使用约束来更改高度并使其工作。这是我发现很容易实现的方式。
回答by clearlight
@startupThekid:
@startupThekid:
iOS will generate an exception if you try to change autoresizing mask for a UINavigationBar that is managed by a UINavigationController.
如果您尝试更改由 UINavigationController 管理的 UINavigationBar 的自动调整大小掩码,iOS 将生成异常。
However, the Swift equivalent of the objective C code you posted is:
但是,与您发布的目标 C 代码等效的 Swift 是:
var navBar = self.navigationController!.navigationBar
in viewDidAppear():
在viewDidAppear() 中:
navBar.setTranslatesAutoresizingMaskIntoConstraints = false
Wherever you need to set the constraint:
无论您需要在哪里设置约束:
var navBarHeightConstraint =
NSLayoutConstraint(item: navBar, attribute: .Height,
relatedBy: .Equal, toItem: nil,
attribute: .Height, multiplier: 1, constant: height)
self.view.addConstraint(navBarHeightConstraint)
Therafter you should be able to modify the constant property of the constraint as necessary to alter the nav bar height, such as for change in device orientation
之后,您应该能够根据需要修改约束的常量属性以更改导航栏高度,例如更改设备方向
回答by Pierre Houston
I was in the same boat and having problems, but now I've fixed it. I'm trying to do the right things to avoid setting the frame explicitly, which is desirable for future-proofing and easy support for different device sizes. In my case, I'm wanting a webview beneath a navigation bar.
我在同一条船上并且遇到了问题,但现在我已经解决了。我正在尝试做正确的事情以避免明确设置框架,这对于面向未来和轻松支持不同设备尺寸是可取的。就我而言,我想要一个导航栏下方的网络视图。
I'm setting my view controller to be a UINavigationBarDelegate
and implementing positionForBar:
to return UIBarPositionTopAttached
, like user3269713's answer. It seemed like the other trick was to use auto-layout to position the bar below the topLayoutGuide.
我将我的视图控制器设置为 aUINavigationBarDelegate
并实现positionForBar:
return UIBarPositionTopAttached
,如user3269713's answer。似乎另一个技巧是使用自动布局将栏定位在 topLayoutGuide 下方。
This wasthe code I was using in viewDidLoad
after creating navigation bar & webview programmatically, and I was still seeing the bar stuck at height 44 but couldn't immediately see why:
这是我在以viewDidLoad
编程方式创建导航栏和 webview 后使用的代码,我仍然看到栏卡在高度 44 处,但无法立即看到原因:
[navigationBar sizeToFit];
navigationBar.delegate = self;
[self.view addSubview:navigationBar];
[self.view addSubview:webView];
id guide = self.topLayoutGuide;
NSDictionary *viewNamesDict = NSDictionaryOfVariableBindings(webView, navigationBar, guide);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[webView]|" options:0 metrics:nil views:viewNamesDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[guide][navigationBar][webView]|" options:0 metrics:nil views:viewNamesDict]];
But I did some more thinking and playing around with auto-layout, and it turns out it that alone was the cause of my problem. I was trying to rely on navigation bar's translated constraints from its autoresizing mask, but it turned out I needed to defined them explicitly. Here's my new viewDidLoad
code that works:
但是我对自动布局进行了更多思考和尝试,结果发现只有我一个人出现问题。我试图依赖导航栏的自动调整大小掩码中的翻译约束,但结果我需要明确定义它们。这是我的新viewDidLoad
代码:
[navigationBar sizeToFit];
navigationBar.delegate = self;
navigationBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:navigationBar];
[self.view addSubview:webView];
id guide = self.topLayoutGuide;
NSDictionary *viewNamesDict = NSDictionaryOfVariableBindings(webView, navigationBar, guide);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[navigationBar]|" options:0 metrics:nil views:viewNamesDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[webView]|" options:0 metrics:nil views:viewNamesDict]];
NSString *verticalLayoutVisualExpression = [NSString stringWithFormat:@"V:|[guide][navigationBar(%f)][webView]|", navigationBar.frame.size.height];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalLayoutVisualExpression options:0 metrics:nil views:viewNamesDict]];
And yes, as I'd hoped, this automatically moves the bar when turning to landscape and the status bar hides.
是的,正如我所希望的,这会在转向横向时自动移动栏并且状态栏隐藏。
(I heartily recommend a auto-layout helper like Masonry which makes layout code more concise, and Masonry, for one, takes care of turning off translatesAutoresizingMaskIntoConstraints
for you)
(我衷心推荐一个像 Masonry 这样的自动布局助手,它使布局代码更简洁,而 Masonry 则是translatesAutoresizingMaskIntoConstraints
为你关闭)