有没有办法在Interface Builder中为Auto Layout Constraints添加标识符?

时间:2015-01-06 03:21:02

标签: ios xcode autolayout interface-builder

在Interface Builder中做了一些可视化布局后,我创建了一些我想在运行时访问的约束。有没有办法在Interface Builder中标记或识别约束,以便以后查找它们?

我想要这样做的原因是我需要根据视觉指定的约束执行一些计算。我知道Apple提供了Visual Format Language,我可以在控制器中以编程方式指定约束。我宁愿不使用这种方法,所以我不会失去IB的设计时反馈。

修改

建立引用插座确实有效,但问题仍然存在。

7 个答案:

答案 0 :(得分:33)

<强>更新

正如BartłomiejSemańczyk在his answer中所解释的那样,NSLayoutConstraint属性检查器中现在可以看到标识符字段,因此不需要自己暴露这个领域。只需在文档大纲视图或Storyboard视图中选择约束,然后在右侧的 Attributes Inspector 中添加标识符。


早期答案:

是的,这可以做到。 NSLayoutConstraint有一个名为identifier的属性,可以在 Interface Builder 中公开并分配。为了演示这个,我创建了一个单视图应用程序,它有一个红色框的子视图。此子视图有4个约束:宽度,高度,在容器中水平居中,在容器中垂直居中。我通过执行以下操作给宽度约束标识符redBoxWidth

  1. 单击文档布局视图中的宽度约束。然后在用户定义的运行时属性下的 Identity Inspector 中,单击密钥路径下的+。将 keyPath 更改为标识符,将类型 布尔更改为 String ,然后设置redBoxWidth

    naming a constraint

  2. 然后在ViewDidLoad中,可以按名称查找约束并更改其值:

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            for subview in view.subviews as [UIView] {
                for constraint in subview.constraints() as [NSLayoutConstraint] {
                    if constraint.identifier == "redBoxWidth" {
                        constraint.constant = 300
                    }
                }
            }
        }
    }
    

答案 1 :(得分:13)

  1. 从Xcode 7开始,您可以在故事板中完成:
  2. enter image description here

    1. 但是,如果在代码中设置约束,请执行以下操作:

      let constraint = NSLayoutConstraint() 
      constraint.identifier = "identifier"
      
    2. 对于您在故事板中设置的这些约束,但您必须在代码中设置标识符:

      for subview in view.subviews {
          for constraint in subview.constraints() {
              constraint.identifier = "identifier"
          }
      }
      

答案 2 :(得分:7)

您也可以像对待任何其他组件一样将约束链接到控制器的属性。只需按住Ctrl键将其拖入您的代码:

enter image description here

然后它可以在控制器的代码中作为属性访问:

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

你可以改变它的价值,例如:

self.myConstraint.constant=100.;

答案 3 :(得分:6)

只需添加@ vacawama的答案。您可以编写UIView类别并使用简单函数提取约束,而不是在需要查找约束的任何位置复制/粘贴循环:

.h文件:

#import <UIKit/UIKit.h>

@interface UIView (EasyAutolayout)

-(NSLayoutConstraint *)constraintForIdentifier:(NSString *)identifier;

@end

.m文件:

#import "UIView+EasyAutolayout.h"

@implementation UIView (EasyAutolayout)

-(NSLayoutConstraint *)constraintForIdentifier:(NSString *)identifier {

    for (NSLayoutConstraint *constraint in self.constraints) {
        if ([constraint.identifier isEqualToString:identifier]) {
            return constraint;
        }
    }
    return nil;
}

@end

答案 4 :(得分:5)

获取自动布局约束的IBOutlet。

NSLayoutConstraint 类中有一个名为常量的属性。

例如,您已经从IB的任何视图中获取了IBOutlet的高度限制,并且您想要以编程方式更改它的高度,您需要做的就是:

 constraint.constant = isMoreHeight ? height1 : height2;

执行此操作后,您需要更新superview的视图层次结构中的所有其他视图。为此,您需要在下面写一行:

[self setLayoutIfNeeded];

为了获得更好的用户体验,您可以将此行放在动画块中,以获得更流畅的过渡效果,

[UIView animateWithDuration:0.3f animations:^{
      [self.view layoutIfNeeded];
}];

希望这会有所帮助..

答案 5 :(得分:4)

这个怎么样:

if let myconstraint = self.view.constraints.filter( { $0.identifier == "myconstraintId" }).first {
    // TODO: your code here...
}

答案 6 :(得分:0)

我为OSX支付2美分(以前的答案与UIKit有关。)

它也适用于OSX:

final private func getConstraintForButton(){
    let constraints  = self.myButton.constraints
    for constraint in constraints  {
        if constraint.identifier == "redBoxWidth" {
            constraint.constant = 300
            break
        }
    }
}

注意:似乎无法在自定义NSView上使用,而是...