web-dev-qa-db-fra.com

Comment modifier les contraintes de disposition automatique après leur définition lors de l'utilisation de constraintEqualToAnchor ()?

J'essaie de configurer une vue avec des contraintes AutoLayout en utilisant constraintEqualToAnchor():

override func viewDidLoad() {
    super.viewDidLoad()

    let myView = UIView()
    myView.backgroundColor = UIColor.orangeColor()
    myView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(myView)

    myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true
    myView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true
    myView.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
    myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true

    /******************************************/
    /* I try to change one of the constraints */
    /******************************************/
    myView.leftAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -100).active = true  
}

Dans la dernière ligne de code, j'essaie de modifier l'une des contraintes. Je pensais que cela fonctionnerait, mais cela donne une erreur dans le journal de la console

"<NSLayoutConstraint:0x7fb53a5180d0 H:|-(0)-[UIView:0x7fb53a5190b0](LTR)   (Names: '|':UIView:0x7fb53a519240 )>",
"<NSLayoutConstraint:0x7fb53a51f660 H:[UIView:0x7fb53a519240]-(-100)-[UIView:0x7fb53a5190b0](LTR)>",
"<NSLayoutConstraint:0x7fb53a711ee0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7fb53a519240(414)]>"

Lorsque vous utilisez constraintEqualToAnchor()?, quel est le bon moyen de modifier la contrainte plus tard, une fois que je les ai définies? 

13
Joe Huang

Vous devez désactiver la contrainte précédente lors de l'activation d'une nouvelle contrainte afin de ne pas trop contraindre votre vue. Pour cela, stockez une référence à chacune des contraintes en tant que propriété dans votre ViewController, puis définissez la propriété active de l'ancienne contrainte sur false avant de créer et d'activer la nouvelle contrainte:

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
    }
}

Mise à jour pour 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
    }
}
32
vacawama

Voici un exemple déclarant une contrainte c qui sera référencée ultérieurement. Nous définissons une nouvelle valeur constante, puis appelons layout dans la vue supérieure.

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()
3
Lucas Derraugh

Voici un exemple avec une instruction IF modifiant un StackView et une vue lorsqu'un segmenté a cliqué:

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
Ahmadiah
// 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
Roman Solodyashkin