有没有办法在视图和xib文件中的顶部布局指南之间添加约束?

在iOS 7中,我们现在可以在视图和顶部布局指南之间添加一个约束,我认为这对解决iOS7中的状态栏偏移问题非常有用(特别是在视图中没有导航栏时)。

在故事板文件中,我可以轻松添加这种约束。 只需按住控制键,然后将视图拖到容器,它将显示“顶部空间到顶部布局指南”选项。

在这里输入图像说明

但是当我在xib文件中做同样的操作时,这个选项就消失了。

在这里输入图像说明

那么,有没有办法在xib文件中添加这种约束呢? 或者我必须添加代码?

你应该参考下面的例子,这肯定会帮助你解决你的问题。 我从http://developer.apple.com得到这个。;

[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] ]; 

这是我的替代解决scheme。

find一个UIView作为一个枢轴,将其顶部布局约束设置为一个固定的垂直空间到容器的顶部。

控制 – 将此布局约束作为IBOutlet拖动,例如

 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *topLayoutConstraint; 

最后,像下面一样重写UIViewController的viewWillLayoutSubviews方法

 - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; self.topLayoutConstraint.constant = [self.topLayoutGuide length] + YOUR_TOP_CONSTRSINT; } 

所有其他视图的顶部约束是基于这个枢轴视图,全部完成:)

直到现在,即使使用XCode 6,我也无法将控件与顶层布局指南alignment.xib文件。 相反,我正在使用另一种方法。

首先,在界面构build器上,我仍然将控件与viewcontroler视图的顶部边界alignment。

然后,在viewDidLoad方法中,我replace了一些约束,以便它们将alignment顶部布局指南而不是主视图:

 - (void)viewDidLoad { [super viewDidLoad]; NSArray *constraints = self.view.constraints; for (NSLayoutConstraint *constraint in constraints) { if ( (constraint.firstItem == self.view) && (constraint.firstAttribute == NSLayoutAttributeTop) ) { NSLayoutConstraint *newConstraint = [self constraint:constraint replaceFirstItemBy:self.topLayoutGuide attribute:NSLayoutAttributeBottom]; [self.view removeConstraint:constraint]; [self.view addConstraint:newConstraint]; } else if ( (constraint.secondItem == self.view) && (constraint.secondAttribute == NSLayoutAttributeTop) ) { NSLayoutConstraint *newConstraint = [self constraint:constraint replaceSecondItemBy:self.topLayoutGuide attribute:NSLayoutAttributeBottom]; [self.view removeConstraint:constraint]; [self.view addConstraint:newConstraint]; } } } - (NSLayoutConstraint*)constraint:(NSLayoutConstraint*)constraint replaceFirstItemBy:(id)newItem attribute:(NSLayoutAttribute)newAttribute { UILayoutPriority priority = constraint.priority; NSLayoutRelation relation = constraint.relation; id secondItem = constraint.secondItem; NSLayoutAttribute secondAttribute = constraint.secondAttribute; CGFloat multiplier = constraint.multiplier; CGFloat constant = constraint.constant; NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:newItem attribute:newAttribute relatedBy:relation toItem:secondItem attribute:secondAttribute multiplier:multiplier constant:constant]; newConstraint.priority = priority; return newConstraint; } - (NSLayoutConstraint*)constraint:(NSLayoutConstraint*)constraint replaceSecondItemBy:(id)newItem attribute:(NSLayoutAttribute)newAttribute { UILayoutPriority priority = constraint.priority; id firstItem = constraint.firstItem; NSLayoutAttribute firstAttribute = constraint.firstAttribute; NSLayoutRelation relation = constraint.relation; CGFloat multiplier = constraint.multiplier; CGFloat constant = constraint.constant; NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:firstItem attribute:firstAttribute relatedBy:relation toItem:newItem attribute:newAttribute multiplier:multiplier constant:constant]; newConstraint.priority = priority; return newConstraint; } 

认为这不是最好的方法,因为我们replace了我们在界面构build器上定义的对象。 但它可能是我们可以考虑的另一种方式。

当然,您不仅可以通过编程方式在视图和top layout guidebottom layout guide之间添加约束,而且还可以借助KVConstraintExtensionsMaster库删除和访问视图与top and bottom layout guide之间的约束。

 // create containerView UIView *containerView = [UIView prepareNewViewForAutoLayout]; [containerView setBackgroundColor:[UIColor brownColor]]; [self.view addSubview:containerView]; // To add Top and Bottom Layout Guide constraint of containerView [self applyTopLayoutGuideConstraintToView:containerView withPadding:0]; [self applyBottomLayoutGuideConstraintToView:containerView withPadding:50]; // To access top Layout Guide Constraint and update it's constant value. NSLayoutConstraint *topLayoutGuideConstraint = [self accessAppliedTopLayoutGuideConstraintFromView:containerView]; topLayoutGuideConstraint.constant = 50; // To access bottom Layout Guide Constraint and update it's constant value with animation NSLayoutConstraint *bottomLayoutGuideConstraint = [self accessAppliedBottomLayoutGuideConstraintFromView:containerView]; bottomLayoutGuideConstraint.constant = 80; [self.view updateModifyConstraintsWithAnimation:NULL]; // call this for animation // To remove Top and Bottom Layout Guide constraint of containerView [self removeAppliedTopLayoutGuideConstraintFromView:containerView]; [self removeAppliedBottomLayoutGuideConstraintFromView:containerView ]; 

从iOS 9开始,您可以使用topLayoutGuide的anchors更简单地进行操作:

  • Swift 3

view.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor).isActive = true

  • ObjC

[self.view.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor].isActive = true

我认为他们没有出现在XIB中的原因是在这种情况下没有关于视图控制器层次结构的知识,而在故事板IB中可以知道视图在视图控制器层次结构中的指南。也就是说,如果包含在UINavigationController中,则可以确定顶部布局指南位于导航工具栏下方。