导航栏和 ViewControllers 视图之间的 NSLayoutConstraint
Posted
技术标签:
【中文标题】导航栏和 ViewControllers 视图之间的 NSLayoutConstraint【英文标题】:NSLayoutConstraint between Navigation Bar & ViewControllers View 【发布时间】:2013-06-12 20:54:42 【问题描述】:我们能否在self.navigationcontroller.navigationbar
和self.view
之间添加一个NSLayoutConstraint
。这里 self 是 UIViewController
实例,_textField
是 self.view
的子视图
我需要的是,无论navigationBar
是否为半透明,UI 都应该看起来相似。
我尝试了以下方法。但它不起作用。
NSLayoutConstraint* cn = [NSLayoutConstraint constraintWithItem:_textField
attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.navigationBar attribute:NSLayoutAttributeBottom
multiplier:1.0 constant:20];
[self.navigationcontroller.view addConstraint:cn];
【问题讨论】:
控制台中有错误信息吗? @Sj.,你有没有想过这个?这里有同样的问题,到处搜索。 @Pat 在花了一些时间之后,我放弃了这种方法。如果您找到任何解决方案,请分享您的解决方案。谢谢。 【参考方案1】:是的,您可以在导航栏和视图之间添加约束。添加到导航控制器的根视图控制器包含 topLayoutGuide。所以像这样调整你的代码:
NSLayoutConstraint* cn = [NSLayoutConstraint constraintWithItem:_textField
attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:self.rootViewController.topLayoutGuide attribute:NSLayoutAttributeBottom
multiplier:1.0 constant:20];
[self.rootViewController.view addConstraint:cn];
请注意,我根本没有引用导航控制器,而是导航控制器的 rootViewController。
您也可以使用 bottomLayoutGuide 以同样的方式进入 TabBar 上方。 (但是,如果您需要这样做,您会在 ios 框架中遇到一个错误,这里有一个解决方法补丁:UIViews ending up beneath tab bar)
【讨论】:
【参考方案2】:查看UIViewController 上的topLayoutGuide
属性。
Apple 的 `UIViewController' 文档中有一个这样的示例...
topLayoutGuide
Indicates the highest vertical extent for your onscreen content, for use with Auto Layout constraints. (read-only)
@property(nonatomic, readonly, retain) id<UILayoutSupport> topLayoutGuide
然后……
作为如何以编程方式将此属性与 Auto 结合使用的示例 布局,假设您要放置一个控件,使其顶部边缘为 低于顶部布局指南 20 点。这种情况适用于任何 上面列出的场景。使用类似于以下的代码:
[button setTranslatesAutoresizingMaskIntoConstraints: NO];
id topGuide = myViewController.topLayoutGuide;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings (button, topGuide);
[myViewController.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat: @"V: [topGuide]-20-[button]"
options: 0
metrics: nil
views: viewsDictionary]
self.view layoutSubviews; // You must call this method here or the system raises an exception
];
【讨论】:
【参考方案3】:在 textField 的顶部和父视图的顶部之间添加约束。约束的常量可以设置为状态栏的高度+导航栏的高度。
显然,下面的代码 sn-p 只有在状态栏和导航栏都是半透明的并且视图控制器想要全屏布局时才有效。如有必要,您可以轻松测试透明度并进行相应调整。
如果您正在使用界面生成器,您还可以为现有约束创建一个 IBOutlet 并将其设置为常量而不是创建新约束。
// Obtain the view rect of the status bar frame in either portrait or landscape
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
CGRect statusBarWindowRect = [self.view.window convertRect:statusBarFrame fromWindow: nil];
CGRect statusBarViewRect = [self.view convertRect:statusBarWindowRect fromView: nil];
// Add Status Bar and Navigation Bar heights together
CGFloat height = self.navigationController.navigationBar.frame.size.height +
statusBarViewRect.size.height;
// Create & Add Constraint
NSLayoutConstraint *constraint =
[NSLayoutConstraint constraintWithItem:self.fieldLabel
attribute:NSLayoutAttributeTop
relatedBy:0
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1
constant:height];
[self.view addConstraint:constraint];
【讨论】:
以上是关于导航栏和 ViewControllers 视图之间的 NSLayoutConstraint的主要内容,如果未能解决你的问题,请参考以下文章
在 UITabBarController 中的标签栏和导航视图之间添加 UIView