Home > Software engineering >  How do you remove constraint centerXAnchor?
How do you remove constraint centerXAnchor?

Time:11-09

I have a button placed in the center using centerXAnchor of superview, but now I have to change the position of the button from centerX to align leading from code. However, it's not moving to the left. Instead, it gets full width button.

buttonView!.translatesAutoresizingMaskIntoConstraints = false

buttonView!.removeConstraints(buttonView!.constraints)

NSLayoutConstraint.activate([
    buttonView!.leadingAnchor.constraint(equalTo: mainView.leadingAnchor, constant: 12),
    buttonView!.bottomAnchor.constraint(equalTo: mainView.bottomAnchor, constant: 20),
])

CodePudding user response:

Removing/add constraints doesn't cause them to be (re)applied.

Call .setNeedsUpdateConstraints() on your view. The system will then call updateConstraints as part of its next layout pass. For complex constraint scenarios you may need your own implementation of updateConstraints, but for most cases, and definitely yours, this won't be needed (and should generally be avoided unless there is a specific reason to use it - see the docs)

CodePudding user response:

first remove all Constraint

extension UIView {

public func removeAllConstraints() {
    var _superview = self.superview
    
    while let superview = _superview {
        for constraint in superview.constraints {
            
            if let first = constraint.firstItem as? UIView, first == self {
                superview.removeConstraint(constraint)
            }
            
            if let second = constraint.secondItem as? UIView, second == self {
                superview.removeConstraint(constraint)
            }
        }
        
        _superview = superview.superview
    }
    
    self.removeConstraints(self.constraints)
    self.translatesAutoresizingMaskIntoConstraints = true
    self.setNeedsUpdateConstraints()
    }
}

to use it

DispatchQueue.main.async { [weak self] in
    self?.buttonView.removeAllConstraints()
   // then you can add your constraint as you like 
}

ref

CodePudding user response:

There are various ways to do this, depending on exactly what you need to accomplish.

First, you said you're laying out your views in Storyboard, so...

If we're talking about one (or a few) specific views, we can create @IBOutlet vars for the constraints you want to change.

In Storyboard:

  • give your buttonView a centerX constraint, with Priority: Required (1000)
  • give your buttonView your desired leading constraint, with Priority: Low (250)

Connect them to outlets:

@IBOutlet var buttonCenterConstraint: NSLayoutConstraint!
@IBOutlet var buttonLeadingConstraint: NSLayoutConstraint!

Then, to switch from centered to leading:

buttonCenterConstraint.priority = .defaultLow
buttonLeadingConstraint.priority = .required

and you can "toggle" it back to centered with:

buttonLeadingConstraint.priority = .defaultLow
buttonCenterConstraint.priority = .required

Perhaps do the same thing with centerY and bottom constraints.

If you want a little more "flexibility," you could do something like this:

  • in Storyboard, set only the centerX constraint

Then, to change that to a leading constraint:

// find the centerX constraint and de-activate it
if let cxConstraint = mainView.constraints.first(where: { ($0.firstAttribute == .centerX && $0.firstItem === buttonView) }) {
    cxConstraint.isActive = false
} else if let cxConstraint = mainView.constraints.first(where: { ($0.firstAttribute == .centerX && $0.secondItem === buttonView) }) {
    cxConstraint.isActive = false
}
// add a new leading constraint
buttonView.leadingAnchor.constraint(equalTo: mainView.leadingAnchor, constant: 12.0).isActive = true
    

You could also use an extension as suggested by someone else to "remove all constraints" ... but you risk removing constraints that you do not want changed.

  • Related