【问题标题】:Is there a way to add an identifier to Auto Layout Constraints in Interface Builder?有没有办法在 Interface Builder 中向 Auto Layout Constraints 添加标识符?
【发布时间】:2015-03-03 16:52:33
【问题描述】:

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

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

编辑

制作参考插座确实有效,但问题仍然存在。

【问题讨论】:

  • 您能否扩展“我也尝试为约束创建一个引用出口,但那也不起作用。”?做一个出口可能是你应该做的。
  • 是的,我回去再试一次,IBOutlet 确实有效。我仍然想知道是否有另一种方法可以用标识符标记约束并稍后查找。
  • 如果 Xcode 为每个约束生成唯一标识符不是很好吗?现在我在哪里?哦,是的,id66id67,……呻吟

标签: ios xcode autolayout interface-builder


【解决方案1】:

我在 OSX 上的两分钱(之前的答案都是关于 UIKit 的。)

它也适用于 OSX:

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

注意:似乎不适用于自定义 NSView,而是...

【讨论】:

    【解决方案2】:

    这个呢:

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

    【讨论】:

      【解决方案3】:

      更新:

      正如 Bartłomiej Semańczyk 在his answer 中所解释的,现在NSLayoutConstraint属性检查器 中有一个可见的Identifier 字段,因此无需公开该字段你自己。只需在 Document Outline 视图或 Storyboard 视图中选择约束,然后在右侧的 Attributes Inspector 中添加一个标识符。


      较早的答案:

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

      1. 单击文档布局视图中的宽度限制。然后在Identity InspectorUser Defined Runtime Attributes下,点击Key Path下的+。将 keyPath 更改为 identifier,将 Type Boolean 更改为 String,并设置redBoxWidth

      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
                        }
                    }
                }
            }
        }
        

      【讨论】:

      • 这是一个非常好的答案。我曾希望有一种更直接的方式来命名 IB 中的约束,但这会奏效。感谢您的出色回答。除了identifier 属性之外,我已经知道其中的大部分内容,并且您将它们很好地组合在一起。
      【解决方案4】:

      您还可以将约束链接到控制器的属性,就像对任何其他组件所做的那样。只需 ctrl 将其拖入您的代码中:

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

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

      您可以更改它的值,例如:

      self.myConstraint.constant=100.;
      

      【讨论】:

        【解决方案5】:
        1. 从 Xcode 7 开始,您可以在情节提要中完成:

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

          let constraint = NSLayoutConstraint() 
          constraint.identifier = "identifier"
          
        2. 对于您在情节提要中设置的这些约束,您必须在代码中设置标识符:

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

        【讨论】:

        • 是否也可以在可视化布局语言中设置 ID?
        【解决方案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
        

        【讨论】:

          【解决方案7】:

          获取自动布局约束的 IBOutlet。

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

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

           constraint.constant = isMoreHeight ? height1 : height2;
          

          完成此操作后,您需要更新父视图的视图层次结构中的所有其他视图。为此,您需要编写以下行:

          [self setLayoutIfNeeded];
          

          为了更好的用户体验,您可以将这条线放在动画块中以获得更平滑的过渡效果,

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

          希望这会有所帮助..

          【讨论】:

          • 我的问题是如何识别 IB 中的约束而不是如何更新它,但无论如何感谢您的回答,因为它确实适合问题的更大范围。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-11
          • 1970-01-01
          • 1970-01-01
          • 2011-06-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多