以编程方式为UIView的子视图设置自动布局约束

时间:2017-04-04 20:22:20

标签: ios swift nslayoutconstraint ios-autolayout

下面我列出了一些代码供您结账。我正在尝试使用自定义UIView并向其添加另一个自定义子视图。这个子视图应该以这样一种方式约束到父视图,它实际上只是在相同的维度上放置,并且父视图只是作为包装器。

到目前为止,我尝试使用NSLayoutConstraint并且失败了。视图从未真正显示出来。我有一个左,右,底部和顶部约束,它应与父视图对齐。

我首先要问的是,有人请在使用以下方法时解释或纠正我的逻辑。我想到的项目参数是你想为(customViewChild)设置约束的实际视图。该属性是指我希望customViewChild的左边缘用于此约束。 relatedBy似乎非常直接,虽然我可能是错的,然后最终toItem指向自我,这是我的CustomViewParent,它也有.left属性来说我希望我的孩子和父母的左边缘排成一行。这个逻辑有缺陷还是我做错了什么呢?

NSLayoutConstraint(item: customViewChild!, 
            attribute: .left, 
            relatedBy: .equal,
            toItem: self,
            attribute: .left, 
            multiplier: 1.0, 
            constant: 0.0)

我知道以下示例可以很容易地用IB完成,但我想了解NSLayoutConstraint,所以请提供相关答案。最后,如果有人能够真正纠正这个代码,那么我有一个有效的例子,那就太棒了。

class CustomViewParent: UIView {

    var customViewChild: UIView?

    override init(frame: CGRect) {
        super.init(frame: frame)

        setConstraints()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        setConstraints()
    }

    func setConstraints() {
        customViewChild = UIView()

        addSubview(customViewChild!)
        customViewChild?.translatesAutoresizingMaskIntoConstraints = false

        let leftConstraint = NSLayoutConstraint(item: customViewChild!, 
            attribute: .left, 
            relatedBy: .equal,
            toItem: self,
            attribute: .left, 
            multiplier: 1.0, 
            constant: 0.0).isActive = true

        let rightConstraint = NSLayoutConstraint(item: customViewChild!, 
            attribute: .right, 
            relatedBy: .equal,
            toItem: self,
            attribute: .right, 
            multiplier: 1.0, 
            constant: 0.0).isActive = true

        let topConstraint = NSLayoutConstraint(item: customViewChild!, 
            attribute: .top, 
            relatedBy: .equal,
            toItem: self,
            attribute: .top,
            multiplier: 1.0, 
            constant: 0.0).isActive = true

        let bottomConstraint = NSLayoutConstraint(item: customViewChild!, 
            attribute: .bottom, 
            relatedBy: .equal,
            toItem: self,
            attribute: .bottom, 
            multiplier: 1.0, 
            constant: 0.0).isActive = true

        customViewChild.addConstraint([leftConstraint, rightConstraint, topConstraint, bottomConstraint]);
    }

}

2 个答案:

答案 0 :(得分:6)

您可能会发现这更容易,更易读......

func setConstraints() {

    if customViewChild == nil {
        customViewChild = UIView()

        addSubview(customViewChild!)
        customViewChild?.translatesAutoresizingMaskIntoConstraints = false

        customViewChild?.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        customViewChild?.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        customViewChild?.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
        customViewChild?.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    }

}

答案 1 :(得分:3)

三件事:

  1. 您无需使用addConstraint。只需将isActive设置为true即可获得约束。
  2. isActive设置为true并将结果分配给常量是没有意义的。设置isActive属性不会返回NSLayoutConstraint。它返回()
  3. 您应该使用.leading.trailing代替.left.right
  4. 通过这些更改,以下内容应该有效:

    func setConstraints() {
        customViewChild = UIView()
    
        addSubview(customViewChild!)
        customViewChild?.translatesAutoresizingMaskIntoConstraints = false
    
        NSLayoutConstraint(item: customViewChild!, 
            attribute: .leading, 
            relatedBy: .equal,
            toItem: self,
            attribute: .leading, 
            multiplier: 1.0, 
            constant: 0.0).isActive = true
    
        NSLayoutConstraint(item: customViewChild!, 
            attribute: .trailing, 
            relatedBy: .equal,
            toItem: self,
            attribute: .trailing, 
            multiplier: 1.0, 
            constant: 0.0).isActive = true
    
        NSLayoutConstraint(item: customViewChild!, 
            attribute: .top, 
            relatedBy: .equal,
            toItem: self,
            attribute: .top,
            multiplier: 1.0, 
            constant: 0.0).isActive = true
    
        NSLayoutConstraint(item: customViewChild!, 
            attribute: .bottom, 
            relatedBy: .equal,
            toItem: self,
            attribute: .bottom, 
            multiplier: 1.0, 
            constant: 0.0).isActive = true
    }