Skip to content

Commit

Permalink
Merge pull request SnapKit#63 from nickynick/remake-constraints
Browse files Browse the repository at this point in the history
Added mas_remakeConstraints
  • Loading branch information
cloudkite committed Apr 29, 2014
2 parents 8de5559 + 1f67395 commit 8e85884
Show file tree
Hide file tree
Showing 13 changed files with 141 additions and 1 deletion.
5 changes: 5 additions & 0 deletions Masonry/MASConstraintMaker.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ typedef NS_OPTIONS(NSInteger, MASAttribute) {
*/
@property (nonatomic, assign) BOOL updateExisting;

/**
* Whether or not to remove existing constraints prior to installing
*/
@property (nonatomic, assign) BOOL removeExisting;

/**
* initialises the maker with a default view
*
Expand Down
6 changes: 6 additions & 0 deletions Masonry/MASConstraintMaker.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ - (id)initWithView:(MAS_VIEW *)view {
}

- (NSArray *)install {
if (self.removeExisting) {
NSArray *installedConstraints = [MASViewConstraint installedConstraintsForView:self.view];
for (MASConstraint *constraint in installedConstraints) {
[constraint uninstall];
}
}
NSArray *constraints = self.constraints.copy;
for (MASConstraint *constraint in constraints) {
constraint.updateExisting = self.updateExisting;
Expand Down
10 changes: 10 additions & 0 deletions Masonry/MASViewConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import "MASViewAttribute.h"
#import "MASConstraint.h"
#import "MASLayoutConstraint.h"
#import "MASUtilities.h"

/**
* A single constraint.
Expand All @@ -35,4 +36,13 @@
*/
- (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute;

/**
* Returns all MASViewConstraints installed with this view as a first item.
*
* @param view A view to retrieve constraints for.
*
* @return An array of MASViewConstraints.
*/
+ (NSArray *)installedConstraintsForView:(MAS_VIEW *)view;

@end
34 changes: 33 additions & 1 deletion Masonry/MASViewConstraint.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,29 @@
#import "MASCompositeConstraint.h"
#import "MASLayoutConstraint.h"
#import "View+MASAdditions.h"
#import <objc/runtime.h>

@interface MAS_VIEW (MASConstraints)

@property (nonatomic, readonly) NSMutableSet *mas_installedConstraints;

@end

@implementation MAS_VIEW (MASConstraints)

static char kInstalledConstraintsKey;

- (NSMutableSet *)mas_installedConstraints {
NSMutableSet *constraints = objc_getAssociatedObject(self, &kInstalledConstraintsKey);
if (!constraints) {
constraints = [NSMutableSet set];
objc_setAssociatedObject(self, &kInstalledConstraintsKey, constraints, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return constraints;
}

@end


@interface MASViewConstraint ()

Expand Down Expand Up @@ -51,7 +74,13 @@ - (id)copyWithZone:(NSZone *)zone {
return constraint;
}

#pragma mark - private
#pragma mark - Public

+ (NSArray *)installedConstraintsForView:(MAS_VIEW *)view {
return [view.mas_installedConstraints allObjects];
}

#pragma mark - Private

- (void)setLayoutConstant:(CGFloat)layoutConstant {
_layoutConstant = layoutConstant;
Expand Down Expand Up @@ -344,6 +373,8 @@ - (void)install {
[self.installedView addConstraint:layoutConstraint];
self.layoutConstraint = layoutConstraint;
}

[firstLayoutItem.mas_installedConstraints addObject:self];
}

- (MASLayoutConstraint *)layoutConstraintSimiliarTo:(MASLayoutConstraint *)layoutConstraint {
Expand All @@ -369,6 +400,7 @@ - (void)uninstall {
[self.installedView removeConstraint:self.layoutConstraint];
self.layoutConstraint = nil;
self.installedView = nil;
[self.firstViewAttribute.view.mas_installedConstraints removeObject:self];
}

@end
11 changes: 11 additions & 0 deletions Masonry/NSArray+MASAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,15 @@
*/
- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;

/**
* Creates a MASConstraintMaker with each view in the callee.
* Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view.
* All constraints previously installed for the views will be removed.
*
* @param block scope within which you can build up the constraints which you wish to apply to each view.
*
* @return Array of created/updated MASConstraints
*/
- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;

@end
9 changes: 9 additions & 0 deletions Masonry/NSArray+MASAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,13 @@ - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block {
return constraints;
}

- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block {
NSMutableArray *constraints = [NSMutableArray array];
for (MAS_VIEW *view in self) {
NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
[constraints addObjectsFromArray:[view mas_remakeConstraints:block]];
}
return constraints;
}

@end
5 changes: 5 additions & 0 deletions Masonry/NSArray+MASShorthandAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block;

@end

Expand All @@ -31,6 +32,10 @@
return [self mas_updateConstraints:block];
}

- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block {
return [self mas_remakeConstraints:block];
}

@end

#endif
11 changes: 11 additions & 0 deletions Masonry/View+MASAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,15 @@
*/
- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;

/**
* Creates a MASConstraintMaker with the callee view.
* Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
* All constraints previously installed for the view will be removed.
*
* @param block scope within which you can build up the constraints which you wish to apply to the view.
*
* @return Array of created/updated MASConstraints
*/
- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;

@end
8 changes: 8 additions & 0 deletions Masonry/View+MASAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *))block {
return [constraintMaker install];
}

- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block {
self.translatesAutoresizingMaskIntoConstraints = NO;
MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
constraintMaker.removeExisting = YES;
block(constraintMaker);
return [constraintMaker install];
}

#pragma mark - NSLayoutAttribute properties

- (MASViewAttribute *)mas_left {
Expand Down
5 changes: 5 additions & 0 deletions Masonry/View+MASShorthandAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block;

@end

Expand Down Expand Up @@ -62,6 +63,10 @@ MAS_ATTR_FORWARD(attribute);
return [self mas_updateConstraints:block];
}

- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block {
return [self mas_remakeConstraints:block];
}

@end

#endif
22 changes: 22 additions & 0 deletions Tests/Specs/MASConstraintMakerSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,28 @@ - (void)testDoNotUpdateConstraints {
expect(constraint2.constant).to.equal(20);
}

- (void)testRemoveConstraints {
MAS_VIEW *newView = MAS_VIEW.new;
[superview addSubview:newView];

maker.left.equalTo(newView).offset(10);
maker.right.equalTo(newView).offset(20);
maker.width.equalTo(newView).offset(30);
[maker install];

expect(superview.constraints).to.haveCountOf(3);
expect([MASViewConstraint installedConstraintsForView:view]).to.haveCountOf(3);

maker.removeExisting = YES;
maker.height.equalTo(newView).offset(100);
[maker install];

expect(superview.constraints).to.haveCountOf(1);
expect([MASViewConstraint installedConstraintsForView:view]).to.haveCountOf(1);
NSLayoutConstraint *constraint1 = superview.constraints[0];
expect(constraint1.constant).to.equal(100);
}

- (void)testCreateNewViewAttributes {
expect(maker.left).notTo.beIdenticalTo(maker.left);
expect(maker.right).notTo.beIdenticalTo(maker.right);
Expand Down
7 changes: 7 additions & 0 deletions Tests/Specs/NSArray+MASAdditionsSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,11 @@ - (void)testShouldSetUpdateExistingForArray {
}];
}

- (void)testShouldSetRemoveExistingForArray {
NSArray *views = @[ MAS_VIEW.new ];
[views mas_remakeConstraints:^(MASConstraintMaker *make) {
expect(make.removeExisting).to.beTruthy();
}];
}

SpecEnd
9 changes: 9 additions & 0 deletions Tests/Specs/View+MASAdditionsSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,13 @@ - (void)testSetUpdateExisting {
expect(newView.translatesAutoresizingMaskIntoConstraints).to.beFalsy();
}

- (void)testSetRemoveExisting {
MAS_VIEW *newView = MAS_VIEW.new;
[newView mas_remakeConstraints:^(MASConstraintMaker *make) {
expect(make.removeExisting).to.beTruthy();
}];

expect(newView.translatesAutoresizingMaskIntoConstraints).to.beFalsy();
}

SpecEnd

0 comments on commit 8e85884

Please sign in to comment.