Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to chain different view attributes #56

Merged
merged 2 commits into from
May 12, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
14 changes: 14 additions & 0 deletions Masonry/MASCompositeConstraint.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,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 multiplier proxies

- (MASConstraint * (^)(CGFloat))multipliedBy {
Expand Down Expand Up @@ -80,6 +87,13 @@ - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(M
};
}

#pragma mark - attribute chaining

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

#pragma mark - Animator proxy

#if TARGET_OS_MAC && !TARGET_OS_IPHONE
Expand Down
7 changes: 7 additions & 0 deletions Masonry/MASConstraint+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
*/
- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation;

/**
* Override to set a custom chaining behaviour
*/
- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute;

@end


Expand All @@ -56,4 +61,6 @@
*/
- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint;

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

@end
23 changes: 21 additions & 2 deletions Masonry/MASConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,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 @@ -204,4 +223,4 @@
*/
- (MASConstraint * (^)(id offset))mas_offset;

@end
@end
80 changes: 67 additions & 13 deletions Masonry/MASConstraint.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#import "MASConstraint.h"
#import "MASConstraint+Private.h"

#define methodNotImplemented() \
#define MASMethodNotImplemented() \
@throw [NSException exceptionWithName:NSInternalInconsistencyException \
reason:[NSString stringWithFormat:@"You must override %@ in a subclass.", NSStringFromSelector(_cmd)] \
userInfo:nil]
Expand Down Expand Up @@ -154,34 +154,88 @@ - (MASConstraint *)with {
return self;
}

- (MASConstraint *)and {
return self;
}

#pragma mark - Chaining

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
MASMethodNotImplemented();
}

- (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 - Abstract

- (MASConstraint * (^)(CGFloat multiplier))multipliedBy { methodNotImplemented(); }
- (MASConstraint * (^)(CGFloat multiplier))multipliedBy { MASMethodNotImplemented(); }

- (MASConstraint * (^)(CGFloat divider))dividedBy { methodNotImplemented(); }
- (MASConstraint * (^)(CGFloat divider))dividedBy { MASMethodNotImplemented(); }

- (MASConstraint * (^)(MASLayoutPriority priority))priority { methodNotImplemented(); }
- (MASConstraint * (^)(MASLayoutPriority priority))priority { MASMethodNotImplemented(); }

- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { methodNotImplemented(); }
- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { MASMethodNotImplemented(); }

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

- (void)setInsets:(MASEdgeInsets)insets { methodNotImplemented(); }
- (void)setInsets:(MASEdgeInsets)insets { MASMethodNotImplemented(); }

- (void)setSizeOffset:(CGSize)sizeOffset { methodNotImplemented(); }
- (void)setSizeOffset:(CGSize)sizeOffset { MASMethodNotImplemented(); }

- (void)setCenterOffset:(CGPoint)centerOffset { methodNotImplemented(); }
- (void)setCenterOffset:(CGPoint)centerOffset { MASMethodNotImplemented(); }

- (void)setOffset:(CGFloat)offset { methodNotImplemented(); }
- (void)setOffset:(CGFloat)offset { MASMethodNotImplemented(); }

#if TARGET_OS_MAC && !TARGET_OS_IPHONE

- (MASConstraint *)animator { methodNotImplemented(); }
- (MASConstraint *)animator { MASMethodNotImplemented(); }

#endif

- (void)install { methodNotImplemented(); }
- (void)install { MASMethodNotImplemented(); }

- (void)uninstall { methodNotImplemented(); }
- (void)uninstall { MASMethodNotImplemented(); }

@end
26 changes: 19 additions & 7 deletions Masonry/MASConstraintMaker.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,22 @@ - (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;
}

- (MASConstraint *)addConstraintWithAttributes:(MASAttribute)attrs {
Expand Down Expand Up @@ -99,6 +107,10 @@ - (MASConstraint *)addConstraintWithAttributes:(MASAttribute)attrs {

#pragma mark - standard Attributes

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

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