Search code examples
ioscocoa-touchautolayoutnslayoutconstraint

Auto-layout margins with anchors


So, I thought the following was equivalent?

# This is how I usually do
contentView.leftAnchor.constraint(equalTo: leftAnchor, constant: 5).isActive = true
contentView.topAnchor.constraint(equalTo: topAnchor, constant: 5).isActive = true
contentView.rightAnchor.constraint(equalTo: rightAnchor, constant: -5).isActive = true
contentView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -5).isActive = true

# This is what I tried. I expected the same result..
layoutMargins = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
contentView.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor).isActive = true
contentView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true
contentView.rightAnchor.constraint(equalTo: layoutMarginsGuide.rightAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor).isActive = true

Though I appear to be wrong. How would I get the 5 margin between the containerView and the parent using margins, constraints and anchors?


Solution

  • I found a solution by reading this question: Auto Layout: layoutMarginsGuide.

    There seems to be an issue when setting layoutMargins from the init.

    Though, instead of setting layoutMargins in viewDidMoveToSuperView I put it in updateConstraints instead, which also worked fine.

    So the code is now:

    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor).isActive = true
        contentView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true
        contentView.rightAnchor.constraint(equalTo: layoutMarginsGuide.rightAnchor).isActive = true
        contentView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor).isActive = true
    }
    
    override func updateConstraints() {
        super.updateConstraints()
        layoutMargins = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
    }
    

    which then had the same effect as:

    contentView.leftAnchor.constraint(equalTo: leftAnchor, constant: 5).isActive = true
    contentView.topAnchor.constraint(equalTo: topAnchor, constant: 5).isActive = true
    contentView.rightAnchor.constraint(equalTo: rightAnchor, constant: -5).isActive = true
    contentView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -5).isActive = true