Search code examples
iosswiftnslayoutconstraintnslayoutanchor

Is best to call .layoutIfNeeded() before or after constraints are changed


I have a button that changes sizes depending on certain situations. I don't need an animation done because the user never sees the change occur. Sometimes when switching back from a smaller size to a larger size the button gets stuck at the smaller size. I think layoutIfNeeded() would fix the problem.

The question is at what point should I call layoutIfNeeded() in the setCameraButtonToNormalSize() function below?

lazy var cameraButton: UIButton = {
    let button = UIButton()
    button.translatesAutoresizingMaskIntoConstraints = false
    button.addTarget(self, action: #selector(cameraButtonPressed), for: .touchUpInside)
    return button
}()

let normalSize: CGFloat = 50
let smallerSize: CGFloat = 5

var cameraButtonWidthConstraint: NSLayoutConstraint?
var cameraButtonHeightConstraint: NSLayoutConstraint?

func setCameraButtonToNormalSize() {

    // before the constraints are changed

    cameraButtonWidthConstraint?.isActive = false
    cameraButtonHeightConstraint?.isActive = false

    cameraButtonWidthConstraint = cameraButton.widthAnchor.constraint(equalToConstant: normalSize)
    cameraButtonWidthConstraint?.isActive = true
    cameraButtonHeightConstraint = cameraButton.heightAnchor.constraint(equalToConstant: normalSize)
    cameraButtonHeightConstraint?.isActive = true

    // after the constraints are changed
}

fileprivate func setCameraButtonToSmallerSize() {

    cameraButtonWidthConstraint?.isActive = false
    cameraButtonHeightConstraint?.isActive = false

    cameraButtonWidthConstraint = cameraButton.widthAnchor.constraint(equalToConstant: smallerSize)
    cameraButtonWidthConstraint?.isActive = true
    cameraButtonHeightConstraint = cameraButton.heightAnchor.constraint(equalToConstant: smallerSize)
    cameraButtonHeightConstraint?.isActive = true
}

Solution

  • You need to call it after

    // after the constraints are changed
     self.view.layoutIfNeeded()