How to change Auto Layout constraints after they are set when using constraintEqualToAnchor()?

前端 未结 4 1348
有刺的猬
有刺的猬 2021-02-04 02:15

I try to set up a view with AutoLayout constraints by using constraintEqualToAnchor():

override func viewDidLoad() {
    super.viewDidLoad()

    le         


        
相关标签:
4条回答
  • 2021-02-04 02:49

    Here is an example declaring a constraint c which will be referenced later in time. We set a new constant value and then call layout on the superview.

    myView.translatesAutoresizingMaskIntoConstraints = false
    
    var constraints: [NSLayoutConstraint] = [
        myView.topAnchor.constraintEqualToAnchor(view.topAnchor),
        myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor),
        myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)
    ]         
    let c = myView.rightAnchor.constraintEqualToAnchor(view.rightAnchor)       
    constraints.append(c)   
    
    view.addSubview(myView)
    NSLayoutConstraint.activateConstraints(constraints)
    
    // Some time later
    c.constant = -100
    view.setNeedsLayout()
    
    0 讨论(0)
  • 2021-02-04 02:58
    // method myView.topAnchor.constraintEqualToAnchor creates new one inactive anchor 
    // and not returns exist with equal relationships     
    
    // you can set identifier for any constraint in Interface Builder or code and find & update in code
    for ( NSLayoutConstraint *c in [self.view constraintsAffectingLayoutForAxis:UILayoutConstraintAxisHorizontal] )
    {
        if ( YES == [c.identifier isEqualToString:@"my.layout-constraint.id"] )
        {
            // Unlike the other properties, the constant can be modified
            // after constraint creation. 
            // Setting the constant on an existing constraint performs much better 
            // than removing the constraint and adding a new one that's exactly like 
            // the old except that it has a different constant.
    
            c.constant = 123;
    
            // if needed
            // [self.view setNeedsUpdateConstraints];
    
            break;
        }
    }
    
    0 讨论(0)
  • 2021-02-04 03:05

    You need to deactivate the previous constraint when activating a new one so that you don't end up over constraining your view. To do that, store a reference to each of the constraints as a property in your ViewController and then set the active property of the old constraint to false before creating and activating the new constraint:

    Swift 2.x:

    class ViewController: UIViewController {
        var leftConstraint: NSLayoutConstraint?
        var trailingConstraint: NSLayoutConstraint?
        var topConstraint: NSLayoutConstraint?
        var bottomConstraint: NSLayoutConstraint?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let myView = UIView()
            myView.backgroundColor = UIColor.orangeColor()
            myView.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(myView)
    
            leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor)
            leftConstraint?.active = true
    
            trailingConstraint = myView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor)
            trailingConstraint?.active = true
    
            topConstraint = myView.topAnchor.constraintEqualToAnchor(view.topAnchor)
            topConstraint?.active = true
    
            bottomConstraint = myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)
            bottomConstraint?.active = true
    
            /******************************************/
            /* I try to change one of the constraints */
            /******************************************/
            leftConstraint?.active = false
            leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -100)
            leftConstraint?.active = true
        }
    }
    

    Update for Swift 3 syntax:

    class ViewController: UIViewController {
        var leftConstraint: NSLayoutConstraint?
        var trailingConstraint: NSLayoutConstraint?
        var topConstraint: NSLayoutConstraint?
        var bottomConstraint: NSLayoutConstraint?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let myView = UIView()
            myView.backgroundColor = UIColor.orange
            myView.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(myView)
    
            leftConstraint = myView.leftAnchor.constraint(equalTo: view.leftAnchor)
            leftConstraint?.isActive = true
    
            trailingConstraint = myView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
            trailingConstraint?.isActive = true
    
            topConstraint = myView.topAnchor.constraint(equalTo: view.topAnchor)
            topConstraint?.isActive = true
    
            bottomConstraint = myView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
            bottomConstraint?.isActive = true
    
            /******************************************/
            /* I try to change one of the constraints */
            /******************************************/
            leftConstraint?.isActive = false
            leftConstraint = myView.leftAnchor.constraint(equalTo: view.rightAnchor, constant: -100)
            leftConstraint?.isActive = true
        }
    }
    
    0 讨论(0)
  • 2021-02-04 03:09

    Here is example with if statement modifying a StackView and View when a segmented clicked:

    if (sender as AnyObject).selectedSegmentIndex == 0{
        // Shrink the white view and stack view
        heightConstraintView = containerView.heightAnchor.constraint(equalToConstant: 100)
        heightConstraintView?.isActive = true
        heightConstraintStackView = stackView.heightAnchor.constraint(equalToConstant: 100)
        heightConstraintStackView?.isActive = true
    } else {
        // Before returning back the white view and stack view DEACTIVATE teh previous constraints
        heightConstraintView?.isActive = false
        heightConstraintStackView?.isActive = false
        // Returning back the white view and stack view to normal size
        heightConstraintView = containerView.heightAnchor.constraint(equalToConstant: 200)
        heightConstraintView?.isActive = true
        heightConstraintStackView = stackView.heightAnchor.constraint(equalToConstant: 200)
        heightConstraintStackView?.isActive = true
    }
    
    0 讨论(0)
提交回复
热议问题