Search code examples
iosswiftautolayout

iOS "UITemporaryLayoutHeight" constraint


I am using systemLayoutSizeFittingSize to get the smallest size for a custom view subclass that satisfies its internal constraints.

let someView = SomeView()        
someView.setNeedsUpdateConstraints()
someView.setNeedsLayout()
someView.layoutIfNeeded()

let viewSize = someView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

println(viewSize) // PRINTS (0.0, 96.0) WHICH IS RIGHT!

I get the correct value but I also get a Unable to simultaneously satisfy constraints warning:

"<NSLayoutConstraint:0x7ff16b753190 '_UITemporaryLayoutHeight' V:[ProjectName.SomeView:0x7ff16b772210(0)]>",
"<NSLayoutConstraint:0x7ff16b75de50 UIImageView:0x7ff16b76eff0.top == ProjectName.SomeView:0x7ff16b772210.topMargin>",
"<NSLayoutConstraint:0x7ff16b7653f0 UIImageView:0x7ff16b76eff0.bottom <= ProjectName.SomeView:0x7ff16b772210.bottomMargin>"

Below is my SomeView UIView subclass.

It just contains an 80x80 imageView pinned to the top, left and bottom margins. (I am using PureLayout to write constraints).

Now obviously this view will have a fixed height of 96 (80 + 8x2 for margins) but theoretically it could stretch if its subviews changed size.

Any ideas? Searching google for UITemporaryLayoutHeight (or Width) gives 0 results...

class SomeView: UIView {

    let imageView = UIImageView()

    var constraintsSet = false

    override init(frame: CGRect) {

        super.init(frame: frame)

        backgroundColor = UIColor.lightGrayColor()

        imageView.backgroundColor = UIColor.darkGrayColor()
        addSubview(imageView)
    }

    override func updateConstraints() {

        if(!constraintsSet) {

            imageView.autoPinEdgeToSuperviewMargin(.Top)
            imageView.autoPinEdgeToSuperviewMargin(.Left)
            imageView.autoPinEdgeToSuperviewMargin(.Bottom, relation: NSLayoutRelation.GreaterThanOrEqual)
            imageView.autoSetDimension(.Width, toSize: 80.0)
            imageView.autoSetDimension(.Height, toSize: 80.0)

            constraintsSet = true
        }
        super.updateConstraints()
    }
}

Solution

  • This:

    It just contains an 80x80 imageView pinned to the top, left and bottom margins

    and this

    NSLayoutConstraint:0x7ff16b753190 '_UITemporaryLayoutHeight' V:[ProjectName.SomeView:0x7ff16b772210(0)]

    is the source of the problem. UIKit is at some point in the load/layout/display process using a height of 0. Since you have constraints to both top and bottom and imageview has its intrinsic content size, you are telling it to fit the image into zero-vertical space.

    The usual way to resolve this is to set either top or bottom constraint's priority to anything less than 1000.