skip to Main Content

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),
])

3

Answers


  1. 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

    Login or Signup to reply.
  2. 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)

    Login or Signup to reply.
  3. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search