使用故事板中设置的标识符来获取对NSLayoutConstraint的引用

时间:2015-10-09 12:34:45

标签: ios objective-c cocoa-touch uistoryboard nslayoutconstraint

我正在使用故事板设置按钮的约束。我看到了一个选项,"标识符"在约束的属性中。

Screenshot of constraint's properties

我想引用这个约束,在代码中改变它的值,移动一个对象。

如何从此标识符中获取对此NSLayoutContraint的引用。

我阅读了文档,它是这样编写的

@interface NSLayoutConstraint (NSIdentifier)
/* For ease in debugging, name a constraint by setting its identifier, which will be printed in the constraint's description.
 Identifiers starting with UI and NS are reserved by the system.
 */
@property (nullable, copy) NSString *identifier NS_AVAILABLE_IOS(7_0);

@end

所以我意识到这是出于调试目的。

如果我想获得它并使用它怎么办?我看到了这个链接,但没有给出令人满意的答案:How to get NSLayoutConstraint's identifier by Its pointer?

6 个答案:

答案 0 :(得分:22)

Swift 3 中,

 let filteredConstraints = button.constraints.filter { $0.identifier == "identifier" }
 if let yourConstraint = filteredConstraints.first {
      // DO YOUR LOGIC HERE
 }

答案 1 :(得分:11)

Swift 3

我编写了一个快速的NSView扩展,可以很好地处理这个问题。

extension NSView {
    func constraint(withIdentifier: String) -> NSLayoutConstraint? {
        return self.constraints.filter { $0.identifier == withIdentifier }.first
    }
}

用法:

if let c = button.constraint(withIdentifier: "my-button-width") {
    // do stuff with c
}

答案 2 :(得分:8)

我假设您为该按钮设置了插座,因此您可以使用该插座。首先,从按钮中检索视图的约束。然后遍历数组并在每次迭代时将每个约束的identifer属性与您在Interface Builder中输入的值进行比较。看起来你在Objective-C编码,所以Objective-C代码示例如下。改变@"标识符"无论你在Interface Builder中设置什么值。

NSArray *constraints = [button constraints];
int count = [constraints count];
int index = 0;
BOOL found = NO;

while (!found && index < count) {
    NSLayoutConstraint *constraint = constraints[index];
    if ( [constraint.identifier isEqualToString:@"identifier"] ) {
        //save the reference to constraint
        found = YES;
    }

    index++;
}

答案 3 :(得分:2)

您可能希望将上一个答案中提供的逻辑外推到扩展中。

extension UIView {
    /// Returns the first constraint with the given identifier, if available.
    ///
    /// - Parameter identifier: The constraint identifier.
    func constraintWithIdentifier(_ identifier: String) -> NSLayoutConstraint? {
        return self.constraints.first { $0.identifier == identifier }
    }
}

然后您可以使用以下任何方式访问任何约束:

myView.constraintWithIdentifier("myConstraintIdentifier")

答案 4 :(得分:1)

我简化了搜索,并增加了超级视图的祖先列表:

var logs = '' // logs needs to be defined for the += operator
const tmp = console.log
console.log = function(...args) {
  // string substitution, console.log style
  const formatArg = util.format(...args)
  logs += formatArg + '\n'
  tmp(...args)
}

// To test it :

console.log('test1')
// use console.log with the "printf" style
console.log('test%d', 2)
// same
console.log('%s%d', 'test', 3)
// now show all the logs that were collected in the global var logs variable
console.log('logs: ', logs) // if you don't like globals, u can also use put it in an attribute of the console object...

答案 5 :(得分:0)

为了调整公共视图容器中的一组按钮的大小,这是有效的。每个子视图/按钮必须使用公共标识符(例如“高度”)。

@IBAction func btnPressed(_ sender: UIButton) {
    for button in self.btnView.subviews{
        for constraint in button.constraints{
            if constraint.identifier == "height"{
                constraint.constant = constraint.constant == 0 ? 30:0
            }
        }
    }
    UIView.animate(withDuration: 0.3) { () -> Void in
        self.view.layoutIfNeeded()
    }
}