CocoaSugar is an Objective-C library that can make developing apps easier. It includes a collection of runtime and Cocoa Touch improvements to solve some practical problem.
COSLayout
is yet another layout library. It's neither a wrapper nor a replacement for Auto Layout. It dose not handle circular references of constraints and constraint priority. Besides that, COSLayout
can solve all layout cases. What's more, COSLayout
provides some additional benefits: smaller memory footprint, better performance and more intuitive expression.
COSLayout
is an abstraction of layout of view. With COSLayout
, you can specify view's layout relative to it's superview, sibling views and non-sibling views. Following example specifies a 10-points constraint from view's bottom to superview's bottom:
UIView *view = [[UIView alloc] init];
COSLayout *layout = [COSLayout layoutOfView:view];
[layout addRule:@"bb = 10"];
In the example above, a rule has been added into layout by method addRule:
. A rule is expressed in Sample Layout Language or "SLL", which can specify constraints intuitively. The syntax of SLL is very simple, just comma-separated assignment expressions. Each assignment expression specifies a constraint, l-value is constraint name, r-value is constraint value.
COSLayout
supports 18 constraints:
Constraint | Direction | Description |
---|---|---|
w |
Horizontal | View's width |
h |
Vertical | View's height |
tt |
Vertical | Space from view's top to superview's top |
tb |
Vertical | Space from view's top to superview's bottom |
ll |
Horizontal | Space from view's left to superview's left |
lr |
Horizontal | Space from view's left to superview's right |
bb |
Vertical | Space from view's bottom to superview's bottom |
bt |
Vertical | Space from view's bottom to superview's top |
rr |
Horizontal | Space from view's right to superview's right |
rl |
Horizontal | Space from view's right to superview's left |
ct |
Vertical | Space from view's center to superview's top |
cl |
Horizontal | Space from view's center to superview's left |
cb |
Vertical | Space from view's center to superview's bottom |
cr |
Horizontal | Space from view's center to superview's right |
minw |
Horizontal | Minimal width of view |
maxw |
Horizontal | Maximal width of view |
minh |
Vertical | Minimal height of view |
maxh |
Vertical | Maximal height of view |
COSLayout
supports 5 constraint value types:
Constraint Value Type | Example | Description |
---|---|---|
CGFloat | 5 -10 20.0 |
Fixed length on screen |
Percentage | 5% -10% 20.0% |
Percentage of superview's width or height |
Format specifier | %tt %w %f |
Constraint value given by additional argument |
Constraint | tt maxw |
Constraint value of current layout |
Nil | nil |
Used to reset a constraint |
Note that the percentage has different means for different constraint directions. If current constraint direction is horizontal, the percentage represents the percentage of superview's width, otherwise, the percentage of superview's height. You can also specify direction of percentage by H:
(horizontal) or V:
(vertical) prefix. For example, H:50%
means 50% width of superview, V:30%
means 30% height of superview.
Format specifier represents a constraint value given by additional argument. For example, %tt
is the space from other view's top to superview's top. Here, the other view is given by additional argument, and the superview is the superview of layout's view. It means that COSLayout
can specify constraints between non-sibling views.
COSLayout
support 20 format specifiers:
Format | Type | Description |
---|---|---|
%tt |
UIView * |
Space from view's top to superview's top |
%tb |
UIView * |
Space from view's top to superview's bottom |
%ll |
UIView * |
Space from view's left to superview's left |
%lr |
UIView * |
Space from view's left to superview's right |
%bb |
UIView * |
Space from view's bottom to superview's bottom |
%bt |
UIView * |
Space from view's bottom to superview's top |
%rr |
UIView * |
Space from view's right to superview's right |
%rl |
UIView * |
Space from view's right to superview's left |
%ct |
UIView * |
Space from view's center to superview's top |
%cl |
UIView * |
Space from view's center to superview's left |
%cb |
UIView * |
Space from view's center to superview's bottom |
%cr |
UIView * |
Space from view's center to superview's right |
%w |
UIView * |
Width of view |
%h |
UIView * |
Height of view |
%f |
CGFloat |
Fixed length on screen |
%p |
CGFloat |
Percentage of superview's width or superview's height |
%^f |
CGFloat(^)(UIView *) |
Space provided by a block |
%^p |
CGFloat(^)(UIView *) |
Percentage provided by a block |
%@f |
id<COSCGFloatProtocol> |
Space provided by an object |
%@p |
id<COSCGFloatProtocol> |
Percentage provided by an object |
Like percentage constraint value, you can also use H:
and V:
prefix to specify direction of percentage. For example, H:%p
, H:%^p
, H:%@p
means percentage is horizontal, V:%p
, V:%^p
, V:%@p
means percentage is vertical.
It is worth mentioning that, format specifier also create a dependency between two views: the layout view and the other view given by additional argument. In COSLayout
, the dependencies is presented by DAG. So COSLayout
do not support the circular dependencies. When superview needs layout, all layouts of subviews will solve it's constraints according to the dependencies.
You can apply arithmetic operator between constraint values. Like other languages, SLL supports 5 basic arithmetic operators:
Operator name | Priority | Associativity | Code examples |
---|---|---|---|
= |
1 | right | tt = 20 ct = 50% |
+= |
1 | right | tt += 20 ct += 50% |
-= |
1 | right | tt -= 20 ct -= 50% |
*= |
1 | right | tt *= 20 ct *= 50% |
/= |
1 | right | tt /= 20 ct /= 50% |
+ |
2 | left | 10 + 20 50% + 10 %w + 5 |
- |
2 | left | 20 - 10 50% - 10 %h - 5 |
* |
3 | left | 50 * 2 80% * 0.5 %h * 2 |
/ |
3 | left | 100 / 2 100% / 2 %h / 2 |
You can also use ()
to group sub-expression to change the evaluation order of expression.
In the following example, COSLayout
aligns view's top-right corner to superview's top-right corner with 5-points space.
UIView *view = [[UIView alloc] init];
COSLayout *layout = [COSLayout layoutOfView:view];
[layout addRule:@"tt = rr = 5"];
In the following example, COSLayout
aligns view's left/bottom/right to superview's left/bottom/right with 10-points space, and make the view's top aligned to superview's center.
UIView *view = [[UIView alloc] init];
COSLayout *layout = [COSLayout layoutOfView:view];
[layout addRule:@"ll = bb = rr = 10, tt = 50%"];
COSObserver
is an improvement of KVO. Using COSObserver
, you can use block for KVO notification. It eliminates some inconvenience of KVO. After making an observation by COSObserver
, there's no need to remove observer manually, COSObserver
can remove observer for target automatically when either observer or target is dealloced.
In the following example, observer
is the observer for label1
. Then, label2
is added to observer
as target. When the text of label2
changed, observer
observes this change immediately and call the block, which makes text of label1
the same as text of label2
.
UILabel *label1 = [[UILabel alloc] init];
UILabel *label2 = [[UILabel alloc] init];
COSObserver *observer = [COSObserver observerForObject:label1];
[observer
addTarget:label2
forKeyPath:@"text"
options:NSKeyValueObservingOptionNew
block:^(id object, id target, NSDictionary *change) {
[target setText:change[NSKeyValueChangeNewKey]];
}];