Skip to content

Commit

Permalink
Merge pull request #55 from Ahti/master
Browse files Browse the repository at this point in the history
add "make.attribute(...)"
  • Loading branch information
cloudkite committed Mar 31, 2014
2 parents 38c135c + c2688ca commit 9a3728c
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 37 deletions.
21 changes: 21 additions & 0 deletions Masonry/MASConstraintMaker.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@
#import "MASConstraint.h"
#import "MASUtilities.h"

typedef NS_OPTIONS(NSInteger, MASAttribute) {
MASAttributeLeft = 1 << NSLayoutAttributeLeft,
MASAttributeRight = 1 << NSLayoutAttributeRight,
MASAttributeTop = 1 << NSLayoutAttributeTop,
MASAttributeBottom = 1 << NSLayoutAttributeBottom,
MASAttributeLeading = 1 << NSLayoutAttributeLeading,
MASAttributeTrailing = 1 << NSLayoutAttributeTrailing,
MASAttributeWidth = 1 << NSLayoutAttributeWidth,
MASAttributeHeight = 1 << NSLayoutAttributeHeight,
MASAttributeCenterX = 1 << NSLayoutAttributeCenterX,
MASAttributeCenterY = 1 << NSLayoutAttributeCenterY,
MASAttributeBaseline = 1 << NSLayoutAttributeBaseline,
};

/**
* Provides factory methods for creating MASConstraints.
* Constraints are collected until they are ready to be installed
Expand All @@ -32,6 +46,13 @@
@property (nonatomic, strong, readonly) MASConstraint *centerY;
@property (nonatomic, strong, readonly) MASConstraint *baseline;

/**
* Returns a block which creates a new MASCompositeConstraint with the first item set
* to the makers associated view and children corresponding to the set bits in the
* MASAttribute parameter. Combine multiple attributes via binary-or.
*/
@property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs);

/**
* Creates a MASCompositeConstraint with type MASCompositeConstraintTypeEdges
* which generates the appropriate MASViewConstraint children (top, left, bottom, right)
Expand Down
66 changes: 40 additions & 26 deletions Masonry/MASConstraintMaker.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,37 @@ - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAtt
return constraint;
}

- (MASConstraint *)addConstraintWithAttributes:(MASAttribute)attrs {
MASAttribute anyAttribute = MASAttributeLeft | MASAttributeRight | MASAttributeTop | MASAttributeBottom | MASAttributeLeading | MASAttributeTrailing | MASAttributeWidth | MASAttributeHeight | MASAttributeCenterX | MASAttributeCenterY | MASAttributeBaseline;

NSAssert((attrs & anyAttribute) != 0, @"You didn't pass any attribute to make.attributes(...)");

NSMutableArray *attributes = [NSMutableArray array];

if (attrs & MASAttributeLeft) [attributes addObject:self.view.mas_left];
if (attrs & MASAttributeRight) [attributes addObject:self.view.mas_right];
if (attrs & MASAttributeTop) [attributes addObject:self.view.mas_top];
if (attrs & MASAttributeBottom) [attributes addObject:self.view.mas_bottom];
if (attrs & MASAttributeLeading) [attributes addObject:self.view.mas_leading];
if (attrs & MASAttributeTrailing) [attributes addObject:self.view.mas_trailing];
if (attrs & MASAttributeWidth) [attributes addObject:self.view.mas_width];
if (attrs & MASAttributeHeight) [attributes addObject:self.view.mas_height];
if (attrs & MASAttributeCenterX) [attributes addObject:self.view.mas_centerX];
if (attrs & MASAttributeCenterY) [attributes addObject:self.view.mas_centerY];
if (attrs & MASAttributeBaseline) [attributes addObject:self.view.mas_baseline];

NSMutableArray *children = [NSMutableArray arrayWithCapacity:attributes.count];

for (MASViewAttribute *a in attributes) {
[children addObject:[[MASViewConstraint alloc] initWithFirstViewAttribute:a]];
}

MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
constraint.delegate = self;
[self.constraints addObject:constraint];
return constraint;
}

#pragma mark - standard Attributes

- (MASConstraint *)left {
Expand Down Expand Up @@ -105,42 +136,25 @@ - (MASConstraint *)baseline {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline];
}

- (MASConstraint *(^)(MASAttribute))attributes {
return ^(MASAttribute attrs){
return [self addConstraintWithAttributes:attrs];
};
}


#pragma mark - composite Attributes

- (MASConstraint *)edges {
NSArray *children = @[
[[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_top],
[[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_left],
[[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_bottom],
[[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_right]
];
MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
constraint.delegate = self;
[self.constraints addObject:constraint];
return constraint;
return [self addConstraintWithAttributes:MASAttributeTop | MASAttributeLeft | MASAttributeRight | MASAttributeBottom];
}

- (MASConstraint *)size {
NSArray *children = @[
[[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_width],
[[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_height]
];
MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
constraint.delegate = self;
[self.constraints addObject:constraint];
return constraint;
return [self addConstraintWithAttributes:MASAttributeWidth | MASAttributeHeight];
}

- (MASConstraint *)center {
NSArray *children = @[
[[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_centerX],
[[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_centerY]
];
MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
constraint.delegate = self;
[self.constraints addObject:constraint];
return constraint;
return [self addConstraintWithAttributes:MASAttributeCenterX | MASAttributeCenterY];
}

#pragma mark - grouping
Expand Down
1 change: 1 addition & 0 deletions Masonry/View+MASAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline;
@property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr);

/**
* a key to associate with this view
Expand Down
7 changes: 7 additions & 0 deletions Masonry/View+MASAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ - (MASViewAttribute *)mas_baseline {
return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBaseline];
}

- (MASViewAttribute *(^)(NSLayoutAttribute))mas_attribute
{
return ^(NSLayoutAttribute attr) {
return [[MASViewAttribute alloc] initWithView:self layoutAttribute:attr];
};
}

#pragma mark - associated properties

- (id)mas_key {
Expand Down
2 changes: 2 additions & 0 deletions Masonry/View+MASShorthandAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
@property (nonatomic, strong, readonly) MASViewAttribute *centerX;
@property (nonatomic, strong, readonly) MASViewAttribute *centerY;
@property (nonatomic, strong, readonly) MASViewAttribute *baseline;
@property (nonatomic, strong, readonly) MASViewAttribute *(^attribute)(NSLayoutAttribute attr);

- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block;
Expand All @@ -51,6 +52,7 @@ MAS_ATTR_FORWARD(height);
MAS_ATTR_FORWARD(centerX);
MAS_ATTR_FORWARD(centerY);
MAS_ATTR_FORWARD(baseline);
MAS_ATTR_FORWARD(attribute);

- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block {
return [self mas_makeConstraints:block];
Expand Down
49 changes: 38 additions & 11 deletions Tests/Specs/MASConstraintMakerSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,31 @@ - (void)setUp {
maker = [[MASConstraintMaker alloc] initWithView:view];
}

- (void)testCreateSingleAttribute {
composite = (MASCompositeConstraint *)maker.attributes(MASAttributeHeight);

expect(composite.childConstraints).to.haveCountOf(1);

MASViewConstraint *viewConstraint = composite.childConstraints[0];
expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view);
expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeHeight);
}

- (void)testCreateAttributes {
composite = (MASCompositeConstraint *)maker.attributes(MASAttributeCenterX | MASAttributeWidth);

expect(composite.childConstraints).to.haveCountOf(2);

// children are ordered like MASAttribute, so the first is width
MASViewConstraint *viewConstraint = composite.childConstraints[0];
expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view);
expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth);

viewConstraint = composite.childConstraints[1];
expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view);
expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeCenterX);
}

- (void)testCreateCenterYAndCenterXChildren {
composite = (MASCompositeConstraint *)maker.center;

Expand All @@ -60,25 +85,27 @@ - (void)testCreateAllEdges {

expect(composite.childConstraints).to.haveCountOf(4);

//top
MASViewConstraint *viewConstraint = composite.childConstraints[0];
expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view);
expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeTop);

MASViewConstraint *viewConstraint;

//left
viewConstraint = composite.childConstraints[1];
viewConstraint = composite.childConstraints[0];
expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view);
expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeLeft);

//bottom

//right
viewConstraint = composite.childConstraints[1];
expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view);
expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeRight);

//top
viewConstraint = composite.childConstraints[2];
expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view);
expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeBottom);
expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeTop);

//right
//bottom
viewConstraint = composite.childConstraints[3];
expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view);
expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeRight);
expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeBottom);
}

- (void)testCreateWidthAndHeightChildren {
Expand Down

0 comments on commit 9a3728c

Please sign in to comment.