Skip to content

Commit

Permalink
add ability to chain different view attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonas Budelmann committed Mar 30, 2014
1 parent 4c6078d commit f784e4f
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 8 deletions.
6 changes: 6 additions & 0 deletions Examples/Masonry iOS Examples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
3DB1CAD5184538E200E91FC5 /* MASExampleArrayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB1CAD4184538E200E91FC5 /* MASExampleArrayView.m */; };
6C87DADA5AB046D9A3181A65 /* libPods-Masonry iOS Examples.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BDC1B8303EED42A2B01B94B1 /* libPods-Masonry iOS Examples.a */; };
DD175E6A182639FB0099129A /* MASExampleUpdateView.m in Sources */ = {isa = PBXBuildFile; fileRef = DD175E69182639FB0099129A /* MASExampleUpdateView.m */; };
DD32C3FD18E8BFF6001F6AD2 /* MASExampleAttributeChainingView.m in Sources */ = {isa = PBXBuildFile; fileRef = DD32C3FC18E8BFF6001F6AD2 /* MASExampleAttributeChainingView.m */; };
DD52F22B179CAD57005CD195 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD52F22A179CAD57005CD195 /* UIKit.framework */; };
DD52F22D179CAD57005CD195 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD52F22C179CAD57005CD195 /* Foundation.framework */; };
DD52F22F179CAD57005CD195 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD52F22E179CAD57005CD195 /* CoreGraphics.framework */; };
Expand All @@ -35,6 +36,8 @@
BDC1B8303EED42A2B01B94B1 /* libPods-Masonry iOS Examples.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Masonry iOS Examples.a"; sourceTree = BUILT_PRODUCTS_DIR; };
DD175E68182639FB0099129A /* MASExampleUpdateView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASExampleUpdateView.h; sourceTree = "<group>"; };
DD175E69182639FB0099129A /* MASExampleUpdateView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASExampleUpdateView.m; sourceTree = "<group>"; };
DD32C3FB18E8BFF6001F6AD2 /* MASExampleAttributeChainingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASExampleAttributeChainingView.h; sourceTree = "<group>"; };
DD32C3FC18E8BFF6001F6AD2 /* MASExampleAttributeChainingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASExampleAttributeChainingView.m; sourceTree = "<group>"; };
DD52F227179CAD57005CD195 /* Masonry iOS Examples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Masonry iOS Examples.app"; sourceTree = BUILT_PRODUCTS_DIR; };
DD52F22A179CAD57005CD195 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
DD52F22C179CAD57005CD195 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -155,6 +158,8 @@
DD9B4D34183CC980002BF408 /* MASExampleScrollView.m */,
3DB1CAD3184538E200E91FC5 /* MASExampleArrayView.h */,
3DB1CAD4184538E200E91FC5 /* MASExampleArrayView.m */,
DD32C3FB18E8BFF6001F6AD2 /* MASExampleAttributeChainingView.h */,
DD32C3FC18E8BFF6001F6AD2 /* MASExampleAttributeChainingView.m */,
);
name = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -280,6 +285,7 @@
DD52F252179CADC0005CD195 /* MASExampleConstantsView.m in Sources */,
DD52F253179CADC0005CD195 /* MASExampleListViewController.m in Sources */,
DD52F254179CADC0005CD195 /* MASExampleSidesView.m in Sources */,
DD32C3FD18E8BFF6001F6AD2 /* MASExampleAttributeChainingView.m in Sources */,
DD52F255179CADC0005CD195 /* MASExampleViewController.m in Sources */,
DDF3875C179D648D00178773 /* MASExampleAnimatedView.m in Sources */,
DD7CC17617ACE990007A469E /* MASExampleDebuggingView.m in Sources */,
Expand Down
13 changes: 13 additions & 0 deletions Examples/Masonry iOS Examples/MASExampleAttributeChainingView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// MASExampleAttributeChainingView.h
// Masonry iOS Examples
//
// Created by Jonas Budelmann on 31/03/14.
// Copyright (c) 2014 Jonas Budelmann. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface MASExampleAttributeChainingView : UIView

@end
77 changes: 77 additions & 0 deletions Examples/Masonry iOS Examples/MASExampleAttributeChainingView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// MASExampleAttributeChainingView.m
// Masonry iOS Examples
//
// Created by Jonas Budelmann on 31/03/14.
// Copyright (c) 2014 Jonas Budelmann. All rights reserved.
//

#import "MASExampleAttributeChainingView.h"

@implementation MASExampleAttributeChainingView

- (id)init {
self = [super init];
if (!self) return nil;

UIView *view1 = UIView.new;
view1.backgroundColor = UIColor.greenColor;
view1.layer.borderColor = UIColor.blackColor.CGColor;
view1.layer.borderWidth = 2;
[self addSubview:view1];

UIView *view2 = UIView.new;
view2.backgroundColor = UIColor.redColor;
view2.layer.borderColor = UIColor.blackColor.CGColor;
view2.layer.borderWidth = 2;
[self addSubview:view2];

UIView *view3 = UIView.new;
view3.backgroundColor = UIColor.blueColor;
view3.layer.borderColor = UIColor.blackColor.CGColor;
view3.layer.borderWidth = 2;
[self addSubview:view3];

UIView *superview = self;
UIEdgeInsets padding = UIEdgeInsetsMake(15, 10, 15, 10);


[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
// chain attributes
make.top.and.left.greaterThanOrEqualTo(superview).insets(padding);

// which is the equivalent of
// make.top.greaterThanOrEqualTo(superview).insets(padding);
// make.left.greaterThanOrEqualTo(superview).insets(padding);

make.bottom.equalTo(view3.mas_top).insets(padding);
make.right.equalTo(view2.mas_left).insets(padding);
make.width.equalTo(view2.mas_width);

make.height.equalTo(@[view2, view3]);
}];

[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
// chain attributes
make.top.and.right.equalTo(superview).insets(padding);

make.left.equalTo(view1.mas_right).insets(padding);
make.bottom.equalTo(view3.mas_top).insets(padding);
make.width.equalTo(view1.mas_width);

make.height.equalTo(@[view1, view3]);
}];

[view3 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(view1.mas_bottom).insets(padding);

// chain attributes
make.left.right.and.bottom.equalTo(superview).insets(padding);

make.height.equalTo(@[view1, view2]);
}];

return self;
}

@end
3 changes: 3 additions & 0 deletions Examples/Masonry iOS Examples/MASExampleListViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#import "MASExampleScrollView.h"
#import "MASExampleLayoutGuideViewController.h"
#import "MASExampleArrayView.h"
#import "MASExampleAttributeChainingView.h"

static NSString * const kMASCellReuseIdentifier = @"kMASCellReuseIdentifier";

Expand Down Expand Up @@ -54,6 +55,8 @@ - (id)init {
viewClass:MASExampleScrollView.class],
[[MASExampleViewController alloc] initWithTitle:@"Array"
viewClass:MASExampleArrayView.class],
[[MASExampleViewController alloc] initWithTitle:@"Attribute Chaining"
viewClass:MASExampleAttributeChainingView.class],
[[MASExampleLayoutGuideViewController alloc] init],
];

Expand Down
62 changes: 62 additions & 0 deletions Masonry/MASCompositeConstraint.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(M
[self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint];
}

- (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
MASConstraint *newConstraint = [self.delegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
newConstraint.delegate = self;
[self.childConstraints addObject:newConstraint];
return newConstraint;
}

#pragma mark - NSLayoutConstraint constant proxies

- (MASConstraint * (^)(MASEdgeInsets))insets {
Expand Down Expand Up @@ -154,6 +161,61 @@ - (MASConstraint *)with {
return self;
}

- (MASConstraint *)and {
return self;
}

#pragma mark - attribute chaining

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
[self constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
return self;
}

- (MASConstraint *)left {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}

- (MASConstraint *)top {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop];
}

- (MASConstraint *)right {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight];
}

- (MASConstraint *)bottom {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom];
}

- (MASConstraint *)leading {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading];
}

- (MASConstraint *)trailing {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing];
}

- (MASConstraint *)width {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth];
}

- (MASConstraint *)height {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
}

- (MASConstraint *)centerX {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX];
}

- (MASConstraint *)centerY {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY];
}

- (MASConstraint *)baseline {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline];
}

#pragma mark - Animator proxy

#if TARGET_OS_MAC && !TARGET_OS_IPHONE
Expand Down
23 changes: 22 additions & 1 deletion Masonry/MASConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,31 @@
*/
- (MASConstraint *)with;

/**
* optional semantic property which has no effect but improves the readability of constraint
*/
- (MASConstraint *)and;

/**
* creates a new MASCompositeConstraint with the called attribute and reciever
*/
- (MASConstraint *)left;
- (MASConstraint *)top;
- (MASConstraint *)right;
- (MASConstraint *)bottom;
- (MASConstraint *)leading;
- (MASConstraint *)trailing;
- (MASConstraint *)width;
- (MASConstraint *)height;
- (MASConstraint *)centerX;
- (MASConstraint *)centerY;
- (MASConstraint *)baseline;

/**
* Sets the constraint debug name
*/
- (MASConstraint * (^)(id key))key;


// NSLayoutConstraint constant Setters
// for use outside of mas_updateConstraints/mas_makeConstraints blocks

Expand Down Expand Up @@ -179,4 +198,6 @@
*/
- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint;

- (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute;

@end
24 changes: 24 additions & 0 deletions Masonry/MASConstraint.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,30 @@ - (id)init {

- (MASConstraint *)with { methodNotImplemented(); }

- (MASConstraint *)and { methodNotImplemented(); }

- (MASConstraint *)left { methodNotImplemented(); }

- (MASConstraint *)top { methodNotImplemented(); }

- (MASConstraint *)right { methodNotImplemented(); }

- (MASConstraint *)bottom { methodNotImplemented(); }

- (MASConstraint *)leading { methodNotImplemented(); }

- (MASConstraint *)trailing { methodNotImplemented(); }

- (MASConstraint *)width { methodNotImplemented(); }

- (MASConstraint *)height { methodNotImplemented(); }

- (MASConstraint *)centerX { methodNotImplemented(); }

- (MASConstraint *)centerY { methodNotImplemented(); }

- (MASConstraint *)baseline { methodNotImplemented(); }

- (MASConstraint * (^)(id key))key { methodNotImplemented(); }

- (void)setInsets:(MASEdgeInsets)insets { methodNotImplemented(); }
Expand Down
26 changes: 19 additions & 7 deletions Masonry/MASConstraintMaker.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,30 @@ - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(M
[self.constraints replaceObjectAtIndex:index withObject:replacementConstraint];
}

#pragma mark - constraint properties

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
- (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute];
MASViewConstraint *constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute];
constraint.delegate = self;
[self.constraints addObject:constraint];
return constraint;
MASViewConstraint *newConstraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute];
if ([constraint isKindOfClass:MASViewConstraint.class]) {
//replace with composite constraint
NSArray *children = @[constraint, newConstraint];
MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];
compositeConstraint.delegate = self;
[self constraint:constraint shouldBeReplacedWithConstraint:compositeConstraint];
return compositeConstraint;
}
if (!constraint) {
newConstraint.delegate = self;
[self.constraints addObject:newConstraint];
}
return newConstraint;
}

#pragma mark - standard Attributes

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute];
}

- (MASConstraint *)left {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}
Expand Down
57 changes: 57 additions & 0 deletions Masonry/MASViewConstraint.m
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,63 @@ - (MASConstraint *)with {
return self;
}

- (MASConstraint *)and {
return self;
}

#pragma mark - attribute chaining


- (MASConstraint *)left {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}

- (MASConstraint *)top {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop];
}

- (MASConstraint *)right {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight];
}

- (MASConstraint *)bottom {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom];
}

- (MASConstraint *)leading {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading];
}

- (MASConstraint *)trailing {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing];
}

- (MASConstraint *)width {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth];
}

- (MASConstraint *)height {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
}

- (MASConstraint *)centerX {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX];
}

- (MASConstraint *)centerY {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY];
}

- (MASConstraint *)baseline {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline];
}

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
NSAssert(!self.hasLayoutRelation, @"Attributes should be chained before defining the constraint relation");

return [self.delegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
}

#pragma mark - Animator proxy

#if TARGET_OS_MAC && !TARGET_OS_IPHONE
Expand Down

0 comments on commit f784e4f

Please sign in to comment.