Merge pull request #55 from Ahti/master
add "make.attribute(...)"
Showing
6 changed files
with
109 additions
and
37 deletions
@@ -9,6 +9,20 @@ | @@ -9,6 +9,20 @@ | ||
9 | #import "MASConstraint.h" | 9 | #import "MASConstraint.h" |
10 | #import "MASUtilities.h" | 10 | #import "MASUtilities.h" |
11 | 11 | ||
12 | +typedef NS_OPTIONS(NSInteger, MASAttribute) { | ||
13 | + MASAttributeLeft = 1 << NSLayoutAttributeLeft, | ||
14 | + MASAttributeRight = 1 << NSLayoutAttributeRight, | ||
15 | + MASAttributeTop = 1 << NSLayoutAttributeTop, | ||
16 | + MASAttributeBottom = 1 << NSLayoutAttributeBottom, | ||
17 | + MASAttributeLeading = 1 << NSLayoutAttributeLeading, | ||
18 | + MASAttributeTrailing = 1 << NSLayoutAttributeTrailing, | ||
19 | + MASAttributeWidth = 1 << NSLayoutAttributeWidth, | ||
20 | + MASAttributeHeight = 1 << NSLayoutAttributeHeight, | ||
21 | + MASAttributeCenterX = 1 << NSLayoutAttributeCenterX, | ||
22 | + MASAttributeCenterY = 1 << NSLayoutAttributeCenterY, | ||
23 | + MASAttributeBaseline = 1 << NSLayoutAttributeBaseline, | ||
24 | +}; | ||
25 | + | ||
12 | /** | 26 | /** |
13 | * Provides factory methods for creating MASConstraints. | 27 | * Provides factory methods for creating MASConstraints. |
14 | * Constraints are collected until they are ready to be installed | 28 | * Constraints are collected until they are ready to be installed |
@@ -33,6 +47,13 @@ | @@ -33,6 +47,13 @@ | ||
33 | @property (nonatomic, strong, readonly) MASConstraint *baseline; | 47 | @property (nonatomic, strong, readonly) MASConstraint *baseline; |
34 | 48 | ||
35 | /** | 49 | /** |
50 | + * Returns a block which creates a new MASCompositeConstraint with the first item set | ||
51 | + * to the makers associated view and children corresponding to the set bits in the | ||
52 | + * MASAttribute parameter. Combine multiple attributes via binary-or. | ||
53 | + */ | ||
54 | +@property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs); | ||
55 | + | ||
56 | +/** | ||
36 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeEdges | 57 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeEdges |
37 | * which generates the appropriate MASViewConstraint children (top, left, bottom, right) | 58 | * which generates the appropriate MASViewConstraint children (top, left, bottom, right) |
38 | * with the first item set to the makers associated view | 59 | * with the first item set to the makers associated view |
@@ -59,6 +59,37 @@ | @@ -59,6 +59,37 @@ | ||
59 | return constraint; | 59 | return constraint; |
60 | } | 60 | } |
61 | 61 | ||
62 | +- (MASConstraint *)addConstraintWithAttributes:(MASAttribute)attrs { | ||
63 | + MASAttribute anyAttribute = MASAttributeLeft | MASAttributeRight | MASAttributeTop | MASAttributeBottom | MASAttributeLeading | MASAttributeTrailing | MASAttributeWidth | MASAttributeHeight | MASAttributeCenterX | MASAttributeCenterY | MASAttributeBaseline; | ||
64 | + | ||
65 | + NSAssert((attrs & anyAttribute) != 0, @"You didn't pass any attribute to make.attributes(...)"); | ||
66 | + | ||
67 | + NSMutableArray *attributes = [NSMutableArray array]; | ||
68 | + | ||
69 | + if (attrs & MASAttributeLeft) [attributes addObject:self.view.mas_left]; | ||
70 | + if (attrs & MASAttributeRight) [attributes addObject:self.view.mas_right]; | ||
71 | + if (attrs & MASAttributeTop) [attributes addObject:self.view.mas_top]; | ||
72 | + if (attrs & MASAttributeBottom) [attributes addObject:self.view.mas_bottom]; | ||
73 | + if (attrs & MASAttributeLeading) [attributes addObject:self.view.mas_leading]; | ||
74 | + if (attrs & MASAttributeTrailing) [attributes addObject:self.view.mas_trailing]; | ||
75 | + if (attrs & MASAttributeWidth) [attributes addObject:self.view.mas_width]; | ||
76 | + if (attrs & MASAttributeHeight) [attributes addObject:self.view.mas_height]; | ||
77 | + if (attrs & MASAttributeCenterX) [attributes addObject:self.view.mas_centerX]; | ||
78 | + if (attrs & MASAttributeCenterY) [attributes addObject:self.view.mas_centerY]; | ||
79 | + if (attrs & MASAttributeBaseline) [attributes addObject:self.view.mas_baseline]; | ||
80 | + | ||
81 | + NSMutableArray *children = [NSMutableArray arrayWithCapacity:attributes.count]; | ||
82 | + | ||
83 | + for (MASViewAttribute *a in attributes) { | ||
84 | + [children addObject:[[MASViewConstraint alloc] initWithFirstViewAttribute:a]]; | ||
85 | + } | ||
86 | + | ||
87 | + MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children]; | ||
88 | + constraint.delegate = self; | ||
89 | + [self.constraints addObject:constraint]; | ||
90 | + return constraint; | ||
91 | +} | ||
92 | + | ||
62 | #pragma mark - standard Attributes | 93 | #pragma mark - standard Attributes |
63 | 94 | ||
64 | - (MASConstraint *)left { | 95 | - (MASConstraint *)left { |
@@ -105,42 +136,25 @@ | @@ -105,42 +136,25 @@ | ||
105 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline]; | 136 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline]; |
106 | } | 137 | } |
107 | 138 | ||
139 | +- (MASConstraint *(^)(MASAttribute))attributes { | ||
140 | + return ^(MASAttribute attrs){ | ||
141 | + return [self addConstraintWithAttributes:attrs]; | ||
142 | + }; | ||
143 | +} | ||
144 | + | ||
108 | 145 | ||
109 | #pragma mark - composite Attributes | 146 | #pragma mark - composite Attributes |
110 | 147 | ||
111 | - (MASConstraint *)edges { | 148 | - (MASConstraint *)edges { |
112 | - NSArray *children = @[ | ||
113 | - [[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_top], | ||
114 | - [[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_left], | ||
115 | - [[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_bottom], | ||
116 | - [[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_right] | ||
117 | - ]; | ||
118 | - MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children]; | ||
119 | - constraint.delegate = self; | ||
120 | - [self.constraints addObject:constraint]; | ||
121 | - return constraint; | 149 | + return [self addConstraintWithAttributes:MASAttributeTop | MASAttributeLeft | MASAttributeRight | MASAttributeBottom]; |
122 | } | 150 | } |
123 | 151 | ||
124 | - (MASConstraint *)size { | 152 | - (MASConstraint *)size { |
125 | - NSArray *children = @[ | ||
126 | - [[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_width], | ||
127 | - [[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_height] | ||
128 | - ]; | ||
129 | - MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children]; | ||
130 | - constraint.delegate = self; | ||
131 | - [self.constraints addObject:constraint]; | ||
132 | - return constraint; | 153 | + return [self addConstraintWithAttributes:MASAttributeWidth | MASAttributeHeight]; |
133 | } | 154 | } |
134 | 155 | ||
135 | - (MASConstraint *)center { | 156 | - (MASConstraint *)center { |
136 | - NSArray *children = @[ | ||
137 | - [[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_centerX], | ||
138 | - [[MASViewConstraint alloc] initWithFirstViewAttribute:self.view.mas_centerY] | ||
139 | - ]; | ||
140 | - MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children]; | ||
141 | - constraint.delegate = self; | ||
142 | - [self.constraints addObject:constraint]; | ||
143 | - return constraint; | 157 | + return [self addConstraintWithAttributes:MASAttributeCenterX | MASAttributeCenterY]; |
144 | } | 158 | } |
145 | 159 | ||
146 | #pragma mark - grouping | 160 | #pragma mark - grouping |
@@ -30,6 +30,7 @@ | @@ -30,6 +30,7 @@ | ||
30 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX; | 30 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX; |
31 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY; | 31 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY; |
32 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline; | 32 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline; |
33 | +@property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr); | ||
33 | 34 | ||
34 | /** | 35 | /** |
35 | * a key to associate with this view | 36 | * a key to associate with this view |
@@ -72,6 +72,13 @@ | @@ -72,6 +72,13 @@ | ||
72 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBaseline]; | 72 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBaseline]; |
73 | } | 73 | } |
74 | 74 | ||
75 | +- (MASViewAttribute *(^)(NSLayoutAttribute))mas_attribute | ||
76 | +{ | ||
77 | + return ^(NSLayoutAttribute attr) { | ||
78 | + return [[MASViewAttribute alloc] initWithView:self layoutAttribute:attr]; | ||
79 | + }; | ||
80 | +} | ||
81 | + | ||
75 | #pragma mark - associated properties | 82 | #pragma mark - associated properties |
76 | 83 | ||
77 | - (id)mas_key { | 84 | - (id)mas_key { |
@@ -27,6 +27,7 @@ | @@ -27,6 +27,7 @@ | ||
27 | @property (nonatomic, strong, readonly) MASViewAttribute *centerX; | 27 | @property (nonatomic, strong, readonly) MASViewAttribute *centerX; |
28 | @property (nonatomic, strong, readonly) MASViewAttribute *centerY; | 28 | @property (nonatomic, strong, readonly) MASViewAttribute *centerY; |
29 | @property (nonatomic, strong, readonly) MASViewAttribute *baseline; | 29 | @property (nonatomic, strong, readonly) MASViewAttribute *baseline; |
30 | +@property (nonatomic, strong, readonly) MASViewAttribute *(^attribute)(NSLayoutAttribute attr); | ||
30 | 31 | ||
31 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; | 32 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; |
32 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; | 33 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; |
@@ -51,6 +52,7 @@ MAS_ATTR_FORWARD(height); | @@ -51,6 +52,7 @@ MAS_ATTR_FORWARD(height); | ||
51 | MAS_ATTR_FORWARD(centerX); | 52 | MAS_ATTR_FORWARD(centerX); |
52 | MAS_ATTR_FORWARD(centerY); | 53 | MAS_ATTR_FORWARD(centerY); |
53 | MAS_ATTR_FORWARD(baseline); | 54 | MAS_ATTR_FORWARD(baseline); |
55 | +MAS_ATTR_FORWARD(attribute); | ||
54 | 56 | ||
55 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { | 57 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { |
56 | return [self mas_makeConstraints:block]; | 58 | return [self mas_makeConstraints:block]; |
@@ -39,6 +39,31 @@ SpecBegin(MASConstraintMaker) { | @@ -39,6 +39,31 @@ SpecBegin(MASConstraintMaker) { | ||
39 | maker = [[MASConstraintMaker alloc] initWithView:view]; | 39 | maker = [[MASConstraintMaker alloc] initWithView:view]; |
40 | } | 40 | } |
41 | 41 | ||
42 | +- (void)testCreateSingleAttribute { | ||
43 | + composite = (MASCompositeConstraint *)maker.attributes(MASAttributeHeight); | ||
44 | + | ||
45 | + expect(composite.childConstraints).to.haveCountOf(1); | ||
46 | + | ||
47 | + MASViewConstraint *viewConstraint = composite.childConstraints[0]; | ||
48 | + expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); | ||
49 | + expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeHeight); | ||
50 | +} | ||
51 | + | ||
52 | +- (void)testCreateAttributes { | ||
53 | + composite = (MASCompositeConstraint *)maker.attributes(MASAttributeCenterX | MASAttributeWidth); | ||
54 | + | ||
55 | + expect(composite.childConstraints).to.haveCountOf(2); | ||
56 | + | ||
57 | + // children are ordered like MASAttribute, so the first is width | ||
58 | + MASViewConstraint *viewConstraint = composite.childConstraints[0]; | ||
59 | + expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); | ||
60 | + expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth); | ||
61 | + | ||
62 | + viewConstraint = composite.childConstraints[1]; | ||
63 | + expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); | ||
64 | + expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeCenterX); | ||
65 | +} | ||
66 | + | ||
42 | - (void)testCreateCenterYAndCenterXChildren { | 67 | - (void)testCreateCenterYAndCenterXChildren { |
43 | composite = (MASCompositeConstraint *)maker.center; | 68 | composite = (MASCompositeConstraint *)maker.center; |
44 | 69 | ||
@@ -60,25 +85,27 @@ SpecBegin(MASConstraintMaker) { | @@ -60,25 +85,27 @@ SpecBegin(MASConstraintMaker) { | ||
60 | 85 | ||
61 | expect(composite.childConstraints).to.haveCountOf(4); | 86 | expect(composite.childConstraints).to.haveCountOf(4); |
62 | 87 | ||
63 | - //top | ||
64 | - MASViewConstraint *viewConstraint = composite.childConstraints[0]; | ||
65 | - expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); | ||
66 | - expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeTop); | ||
67 | - | 88 | + MASViewConstraint *viewConstraint; |
89 | + | ||
68 | //left | 90 | //left |
69 | - viewConstraint = composite.childConstraints[1]; | 91 | + viewConstraint = composite.childConstraints[0]; |
70 | expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); | 92 | expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); |
71 | expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeLeft); | 93 | expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeLeft); |
72 | - | ||
73 | - //bottom | 94 | + |
95 | + //right | ||
96 | + viewConstraint = composite.childConstraints[1]; | ||
97 | + expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); | ||
98 | + expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeRight); | ||
99 | + | ||
100 | + //top | ||
74 | viewConstraint = composite.childConstraints[2]; | 101 | viewConstraint = composite.childConstraints[2]; |
75 | expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); | 102 | expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); |
76 | - expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeBottom); | 103 | + expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeTop); |
77 | 104 | ||
78 | - //right | 105 | + //bottom |
79 | viewConstraint = composite.childConstraints[3]; | 106 | viewConstraint = composite.childConstraints[3]; |
80 | expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); | 107 | expect(viewConstraint.firstViewAttribute.view).to.beIdenticalTo(maker.view); |
81 | - expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeRight); | 108 | + expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeBottom); |
82 | } | 109 | } |
83 | 110 | ||
84 | - (void)testCreateWidthAndHeightChildren { | 111 | - (void)testCreateWidthAndHeightChildren { |
-
Please register or login to post a comment