简体   繁体   English

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

[英]Is there a way to add an identifier to Auto Layout Constraints in Interface Builder?

After doing some visual layout in Interface Builder I've created some constraints that I want to access at runtime. 在Interface Builder中进行了一些可视化布局后,我创建了一些我想在运行时访问的约束。 Is there a way to label or identify constraints in Interface Builder so they can be looked-up later? 有没有办法在Interface Builder中标记或识别约束,以便以后查找它们?

The reason I want to do this is I need to perform some calculation base upon the constraints that are visually specified. 我想要这样做的原因是我需要根据视觉指定的约束执行一些计算。 I am aware that Apple has provided the Visual Format Language and I could specify the constraints programmatically in a controller. 我知道Apple提供了可视格式语言 ,我可以在控制器中以编程方式指定约束。 I rather not use this approach so I don't lose the design time feedback of IB. 我宁愿不使用这种方法,所以我不会失去IB的设计时反馈。

Edit 编辑

Making a referencing outlet did work, but the question still stands. 建立引用插座确实有效,但问题仍然存在。

Update: 更新:

As explained by Bartłomiej Semańczyk in his answer , there is now an Identifier field visible in the Attributes Inspector for the NSLayoutConstraint making it unnecessary to expose this field yourself. 正如BartłomiejSemańczyk在他的回答中所解释的那样,现在在属性检查器中可以看到NSLayoutConstraint标识符字段,因此不必自己公开该字段。 Just select the constraint in the Document Outline view or in the Storyboard view and then add an identifier in the Attributes Inspector on the right. 只需在“ 文档大纲”视图或“故事板”视图中选择约束,然后在右侧的“ 属性”检查器中添加标识符。


Earlier Answer: 早期答案:

Yes, this can be done. 是的,这可以做到。 NSLayoutConstraint has a property called identifier than can be exposed in Interface Builder and assigned. NSLayoutConstraint有一个名为identifier的属性,可以在Interface Builder中公开并分配。 To demo this, I created a Single View Application that has a single subview that is a red box. 为了演示这个,我创建了一个单视图应用程序 ,它有一个红色框的子视图。 This subview has 4 constraints: width, height, centered horizontally in container, centered vertically in container. 此子视图有4个约束:宽度,高度,在容器中水平居中,在容器中垂直居中。 I gave the width constraint the identifier redBoxWidth by doing the following: 我通过执行以下操作给宽度约束标识符redBoxWidth

  1. Click on the width constraint in the Document Layout View . 单击“ 文档布局视图”中的宽度约束。 Then in the Identity Inspector under User Defined Runtime Attributes , click on the + under Key Path . 然后在“ 用户定义的运行时属性”下的“ 标识检查器 ”中,单击“ 密钥路径”下的“ + ”。 Change keyPath to identifier , change the Type Boolean to String , and set the Value to redBoxWidth . keyPath更改为identifier ,将Type Boolean更改为String ,并将Value设置为redBoxWidth

    命名约束

  2. Then in ViewDidLoad it is possible to find the constraint by name and change its value: 然后在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. Since Xcode 7 you can do it in storyboard: 从Xcode 7开始,您可以在故事板中完成:

在此输入图像描述

  1. However if you set up your constraint in code, do the following: 但是,如果在代码中设置约束,请执行以下操作:

     let constraint = NSLayoutConstraint() constraint.identifier = "identifier" 
  2. For these constraints you have set up in storyboard, but you must set identifier in code: 对于您在故事板中设置的这些约束,但您必须在代码中设置标识符:

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

Also you could link constraint to properties of your controller as you do for any other components. 您也可以像对任何其他组件一样将约束链接到控制器的属性。 Just ctrl drag it into your code: 只需按住Ctrl键将其拖入您的代码:

在此输入图像描述

And then it will be accessible in code of your controller as property: 然后它将在您的控制器的代码中作为属性访问:

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

And you could change it value for example: 你可以改变它的价值,例如:

self.myConstraint.constant=100.;

Just adding on to @vacawama's answer. 只需添加@ vacawama的答案。 You can write a UIView category and pull out constraints using a simple function, as opposed to copy/pasting loops everywhere you need to find a constraint: 您可以编写UIView类别并使用简单函数提取约束,而不是在需要查找约束的任何位置复制/粘贴循环:

.h file: .h文件:

#import <UIKit/UIKit.h>

@interface UIView (EasyAutolayout)

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

@end

.m file: .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

Take the IBOutlet of your auto layout constraint. 获取自动布局约束的IBOutlet。

There is one property called constant in the NSLayoutConstraint class. NSLayoutConstraint类中有一个名为constant的属性。

For eg, you've taken the IBOutlet of height constraint of any of the views from your IB, and you want to change it's height programmatically, all you need to do is: 例如,您已经从IB的任何视图中获取了IBOutlet的高度约束,并且您想要以编程方式更改它的高度,您需要做的就是:

 constraint.constant = isMoreHeight ? height1 : height2;

After doing this, you need to update all other views in the view hierarchy of the superview. 执行此操作后,您需要更新superview的视图层次结构中的所有其他视图。 To do this you'll need to write below line: 为此,您需要在下面写一行:

[self setLayoutIfNeeded];

For better user experience, you can put this line inside your animations block for smoother transition effects, 为了获得更好的用户体验,您可以将此行放在动画块中,以获得更平滑的过渡效果,

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

Hope this helps.. 希望这可以帮助..

What about this: 那这个呢:

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

my two cents for OSX (previous answers deal with UIKit..) 我对OSX的两分钱(之前的答案与UIKit有关......)

it work for OSX, too: 它也适用于OSX:

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

Note: seems NOT working on custom NSView, instead... 注意:似乎不适用于自定义NSView,而是......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM