Authored by Jonas Budelmann

Merge pull request #55 from Ahti/master

add "make.attribute(...)"
... ... @@ -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
... ... @@ -33,6 +47,13 @@
@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)
* with the first item set to the makers associated view
... ...
... ... @@ -59,6 +59,37 @@
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 {
... ... @@ -105,42 +136,25 @@
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
... ...
... ... @@ -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
... ...
... ... @@ -72,6 +72,13 @@
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 {
... ...
... ... @@ -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;
... ... @@ -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];
... ...
... ... @@ -39,6 +39,31 @@ SpecBegin(MASConstraintMaker) {
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;
... ... @@ -60,25 +85,27 @@ SpecBegin(MASConstraintMaker) {
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 {
... ...