Read about the motivation and creation of these categories.
JBNSLayoutConstraint is a set of Objective-C categories that adds string-based linear equations and installation assistance to Auto Layout constraints.
As an example, this single method creates four constraints and adds each constraint to its closest ancestor view:
[NSLayoutConstraint
jb_installConstraintsWithVisualFormat:@"view1.center==|;view1.size==50.0"
options:0
metrics:nil
views:@{ @"view1" : view1 }]];
Overview
JBNSLayoutConstraint+LinearEquation.h makes it easy to create constraints using a string-based linear equation of the following form:
view1.attr1 == view2.attr2 * multiplier + constant @ priority
Multiple expressions can be passed by separating them with a semicolon, and linear equations can be mixed with NSLayoutConstraint’s existing ASCII art-like visual format strings.
JBNSLayoutConstraint+Install.h adds methods to automatically install (and uninstall) one or more constraints on the closest common ancestor of each constraint’s involved views.
There are many NSLayoutConstraint categories out there, but I wanted one that allowed me to easily pass multiple visual format strings to a single method and also allowed me to express constraints using string-based linear equations. Basically, I just wanted to type less code.
Requirements
The JBNSLayoutConstraint categories have been built and tested for iOS, and they have the same requirements as Auto Layout: iOS 6.0 and later. Also, while these categories may work for Mac development (and NSView) with slight modification, I have not tried this myself.
Download
The Xcode 5 project includes a set of unit tests and a quick-and-dirty sample app that makes it easy to experiment with formats and expressions.
JBNSLayoutConstraint on Github
The sample app includes three views (view1, view2, and view3) and three metrics (metric1, metric2, and metric3). If a view has ambiguous layout (view.hasAmbiguousLayout == YES
), its border will be red. Otherwise, its border is green.
JBNSLayoutConstraint+LinearEquation.h
To add string-based linear equation support to a project, simply:
#import "JBNSLayoutConstraint+LinearEquation.h"
Then, you can replace a traditional NSLayoutConstraint method like this:
[NSLayoutConstraint
constraintWithItem:view1
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:view1.superview
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0.0f];
…with a string-based linear equation:
[NSLayoutConstraint
jb_constraintsWithVisualFormat:@"view1.centerX==|.centerX"
options:0
metrics:nil
views:@{ @"view1" : view1 }];
Like Auto Layout’s visual format, the pipe character (|
) references the view’s superview.
While this isolated example isn’t much shorter, the true power of the category can be seen when creating multiple constraints:
[NSLayoutConstraint
jb_constraintsWithVisualFormat:@"view1.center==|;view1.size==50"
options:0
metrics:nil
views:@{ @"view1" : view1 }];
This example uses two of the three compound attributes that are included with the category: center, frame, and size. These compound attributes are automatically expanded to include an appropriate set of constraints. In this example, center expands to include attributes for both centerX and centerY, and size expands to width and height.
Also note that the second center attribute in the first expression has been omitted, because both attributes of the constraint are the same.
As mentioned, linear equations can be mixed with Auto Layout’s visual format to pass multiple expression types:
[NSLayoutConstraint
jb_constraintsWithVisualFormat:@"H:|[view1(20)];V:|[view1];view1.height==metric1"
options:0
metrics:@{ @"metric1" : @(42) },
views:@{ @"view1" : view1 }];
Compound Attributes
The three compound attributes expand to include multiple constraints (in these orders):
- center expands to: centerX, centerY
- size expands to: width, height
- frame expands to: top, left, bottom, right
JBNSLayoutConstraint+Install.h
To install and uninstall one or more constraints, first:
#import "JBNSLayoutConstraint+Install.h"
Then, to install a constraint on the closest common ancestor of its involved views:
NSLayoutConstraint *constraint = ...;
[constraint jb_install];
Note that this also sets translatesAutoresizingMaskIntoConstraints
to NO
for the involved views.
To uninstall a constraint:
[constraint jb_uninstall];
To install multiple constraints, each to the closest common ancestor of its involved views:
NSArray *constraints = [NSLayoutConstraint jb_constraintsWithVisualFormat:...];
[NSLayoutConstraint jb_installConstraints:constraints];
Like jb_install
, this sets translatesAutoresizingMaskIntoConstraints
to NO
for the involved views of each constraint.
Similarly, to uninstall multiple constraints:
[NSLayoutConstraint jb_uninstallConstraints:constraints];
Finally, to generate and install multiple constraints in a single call:
[NSLayoutConstraint
jb_installConstraintsWithVisualFormat:@"view1.centerX==|"
options:0
metrics:nil
views:@{ @"view1" : view1 }];
Feedback
As always, I’d love your feedback.