我想在我的一个视图中使用自定义UINavigationBar
,这不是任何UINavigationController
层次结构的一部分。当我将UINavigationBar
拖到Storyboard中时,它显示如下:
此栏为44px,如果状态栏不共享此空间就足够了。因为iOS7允许我们使用整个屏幕,包括状态栏的空间,UINavigationBar
应该是64px高,而不是44px。
如果我将视图连接到UINavigationController
的层次结构,那么它显示正确:
我在某处读到如果 UINavigationBar
将属性barPosition:
设置为UIBarPositionTopAttached
,那么该栏将为64px。但是,这是readonly
- 属性。
我的搜索结果只显示了我认为是“解决方法”的问题。通过在此UINavigationController
之前添加无用的UIViewController
,我可以假装有一个层次结构,它会自动添加UINavigationBar
64px。
是否真的没有办法覆盖64px的'流氓'(没有导航控制器的帮助)UINavigationBar
?
如果是这种情况,是否有任何正当理由?
(我不是说默认情况下UINavigationBar
应该是64px,但在检查器中应该有一个选项)
(我也看到人们用程序化的方式来解决这个问题。即使这些答案有效,我仍然必须设计故事板,考虑到这一点(差距)。我想要什么要知道是否可以在故事板中设置它,或者更确切地说,为什么不允许它?)
答案 0 :(得分:45)
您可以将属性barPosition
另设为UIBarPositionTopAttached
!
在委托类中实施-positionForBar:
:
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
return UIBarPositionTopAttached;
}
您的导航栏顶部也必须固定在顶部布局指南中。
答案 1 :(得分:25)
您可以通过编程方式更改导航栏高度:
[navBar setFrame:CGRectMake(0, 0, 320, 64)];
编辑:正如我在评论中写的那样,您可能必须在viewDidLayoutSubviews
中放置这一行以规避自动布局。
答案 2 :(得分:10)
您可以使用&#39;用户定义的运行时属性&#39;将其设置为附加到视图的顶部。在身份检查员&#39;在Interface Builder中。设置barPosition
属性。
以下是barPosition
媒体资源的文档:https://developer.apple.com/library/ios/documentation/uikit/reference/UIBarPositioning_Protocol/Reference/Reference.html
答案 3 :(得分:8)
有一种方法可以在不使用UINavigationController
或以编程方式设置它的情况下完成此操作。只需在导航栏上将高度约束设置为您想要的任何值,在此实例中为64。
您可以通过编程方式完成相同的操作:
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:navigationBar attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1 constant:64.0f]];
编辑:
正如@ nerdist-colony指出的那样,在使用Autolayout时,始终将translatesAutoresizingMaskIntoConstraints
设置为NO
,否则可能会出现约束冲突。
答案 4 :(得分:3)
我也使用独立的UINavigationBar,我遇到了同样的问题,我发现有两种方法可以正确解决这个问题。
我使用约束和父UIView修复它。我在故事板中将此UIView设置为具有{0,0,320,64}帧的UINavigationBar的父视图。您可以添加约束或一组约束,强制UINavigationBar具有所需的大小。 鉴于您的父UIView在故事板中具有正确的框架,您可以像往常一样在故事板中布置其他视图。
现在,如果禁用autolayout,您可以按照Lindsey的答案中的描述以编程方式更改条形高度。
-(void)viewDidLayoutSubviews
似乎是一个很好的选择。
答案 5 :(得分:2)
如果您使用Autolayout,则可以将UINavigationBar约束的高度设置为64或更多事件。
答案 6 :(得分:1)
@startupThekid:
如果您尝试更改由UINavigationController管理的UINavigationBar的自动调整掩码,iOS将生成异常。
但是,您发布的目标C代码的Swift等价物是:
var navBar = self.navigationController!.navigationBar
viewDidAppear ()中的:
navBar.setTranslatesAutoresizingMaskIntoConstraints = false
无论您何时需要设置约束:
var navBarHeightConstraint =
NSLayoutConstraint(item: navBar, attribute: .Height,
relatedBy: .Equal, toItem: nil,
attribute: .Height, multiplier: 1, constant: height)
self.view.addConstraint(navBarHeightConstraint)
之后您应该能够根据需要修改约束的常量属性以更改导航栏高度,例如更改设备方向
答案 7 :(得分:1)
我写了一篇博文,详细介绍了如何通过最少的代码干预来完成这项工作。您的栏会在故事板中显示间隙,但它可以在设备上正常工作。简而言之,步骤是:
1)将导航栏添加到故事板中的视图控制器。
2)在故事板中设置导航栏的约束:
- 导航栏。顶部=顶部布局指南。底部
- 导航栏。领导= Superview.Leading
- 导航Bar.Trailing = Superview.Trailing
3)将storyboard的导航栏作为@IBOutlet连接到其视图控制器。
4)在视图控制器的类中,将UINavigationBarDelegate协议添加到类声明中。
5)在视图控制器的viewDidLoad方法中,将导航栏的委托设置为self。
6)在视图控制器中,添加条形定位委托的positionForBar方法。返回表示TopAttached的UIBarPosition。 (注意:UINavigationBarDelegate从UIBarPositioningDelegate继承此方法。)
GIF图片的完整帖子在这里:
Easily use a Navigation Bar without a corresponding Navigation Controller
这些步骤适用于Swift 2.1 / Xcode 7.2
答案 8 :(得分:1)
在使用主故事板的Swift 3中,您可以使用约束来更改高度并使其工作。这是我发现易于实现的方式。
答案 9 :(得分:0)
我在同一条船上遇到问题,但现在我已经修好了。我正在尝试做正确的事情以避免明确地设置框架,这对于面向未来并且容易支持不同的设备尺寸是可取的。就我而言,我想在导航栏下面看一个webview。
我将视图控制器设置为UINavigationBarDelegate
并实施positionForBar:
以返回UIBarPositionTopAttached
,例如user3269713's answer。似乎另一个技巧是使用自动布局将栏定位在topLayoutGuide下方。
这个是创建导航栏后我在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]];
但是我做了一些更多的思考并玩弄了自动布局,事实证明这就是我的问题的原因。我试图依靠导航栏自动调整掩码的翻译约束,但事实证明我需要明确定义它们。这是我的新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]];
是的,正如我所希望的那样,当转向横向并隐藏状态栏时,这会自动移动横杆。
(我衷心推荐一个像砌体一样的自动布局助手,它使布局代码更加简洁,而Masonry为一个人负责为你关掉translatesAutoresizingMaskIntoConstraints
答案 10 :(得分:0)
我知道这是一种非常黑客的做法,但对我来说这很有用。我有一个NavigationViewController
,我希望以模式方式加载一个ViewController,其顶部有一个UINavigationBar
,带有Done和Cancel按钮。这就是它的样子:
正如您所看到的,顶部有一条白色条带,我想要与UINavigationBar
颜色相同。我没有以编程方式更改UINavigationBar
的高度,而是创建了一个新视图并将其背景颜色设置为等于UINavigationBar
的背景颜色(HEX = F8F8F8,RGBA = 248,248,248,1.0)。再一次,我知道这是超级hacky,但它为我完成了工作。这就是现在的样子