Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS constraint style: addConstraints vs .isActive = true

I have some code which is creating auto-layout constraints programatically, and adding them to a view.

There are two ways to do this - call addConstraints on the superView, or set .isActive = true on each constraint (which internally calls addConstraint)

Option 1:

parent.addConstraints([
    child.topAnchor.constraint(equalTo: parent.topAnchor, constant: 20),
    child.leftAnchor.constraint(equalTo: parent.leftAnchor, constant: 5) ])

Option 2:

child.topAnchor.constraint(equalTo: parent.topAnchor, constant: 20).isActive = true
child.leftAnchor.constraint(equalTo: parent.leftAnchor, constant: 5).isActive = true

My question is, is there any benefit to doing one over the other? (performance/etc) or does it come purely down to style.

(I don't think constraints are evaluated until the next layout pass, so I don't think it should matter that we add them one-by-one instead of in a block??)

If it is just style, what's the "more preferred" style by the community??

(personally I prefer addConstraints, however it's very close and I could be easily swayed to .isActive)

like image 814
Orion Edwards Avatar asked Oct 09 '16 00:10

Orion Edwards


People also ask

How do you add constraints in storyboard IOS?

Open the Align menu with the yellow button selected and check Horizontally in Container, then click Add 1 Constraint. Now, select both buttons at the same time using the Shift key and, in the Align menu, check Leading Edges. Again, actually install the constraint by clicking Add 1 Constraint.

How do I set constraints programmatically in Objective C?

NSLayoutConstraint *centreHorizontallyConstraint = [NSLayoutConstraint constraintWithItem:self. uiButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self. view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]; [self. view addConstraint:centreHorizontallyConstraint];


1 Answers

According to the documentation on addConstraint: setting the active property is recommended for individual constraints. (note: active property is only available iOS 8+).

When developing for iOS 8.0 or later, set the constraint’s active property to YES instead of calling the addConstraint: method directly. The active property automatically adds and removes the constraint from the correct view. (reference)

Also if you look at the interface definition for addConstraint: it has this comment:

// This method will be deprecated in a future release and should be avoided.  Instead, set NSLayoutConstraint's active property to YES


With that being said, there is actually a 3rd [and probably better] alternative, which is to use NSLayoutConstraint's class method activate::

NSLayoutConstraint.activate([
    child.topAnchor.constraint(equalTo: parent.topAnchor, constant: 20),
    child.leftAnchor.constraint(equalTo: parent.leftAnchor, constant: 5) ])

This is also a recommended solution according to the documentation and interface files. So if you have multiple constraints, this would be an easy solution and probably preferred in your situation.

(interface comment; emphasis mine):

Convenience method that activates each constraint in the contained array, in the same manner as setting active=YES. This is often more efficient than activating each constraint individually.

like image 172
Firo Avatar answered Oct 13 '22 19:10

Firo