123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- //
- // MASConstraintMaker.m
- // Masonry
- //
- // Created by Jonas Budelmann on 20/07/13.
- // Copyright (c) 2013 cloudling. All rights reserved.
- //
- #import "MASConstraintMaker.h"
- #import "MASViewConstraint.h"
- #import "MASCompositeConstraint.h"
- #import "MASConstraint+Private.h"
- #import "MASViewAttribute.h"
- #import "View+MASAdditions.h"
- @interface MASConstraintMaker () <MASConstraintDelegate>
- @property (nonatomic, weak) MAS_VIEW *view;
- @property (nonatomic, strong) NSMutableArray *constraints;
- @end
- @implementation MASConstraintMaker
- - (id)initWithView:(MAS_VIEW *)view {
- self = [super init];
- if (!self) return nil;
-
- self.view = view;
- self.constraints = NSMutableArray.new;
-
- return self;
- }
- - (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;
- [constraint install];
- }
- [self.constraints removeAllObjects];
- return constraints;
- }
- #pragma mark - MASConstraintDelegate
- - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint {
- NSUInteger index = [self.constraints indexOfObject:constraint];
- NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
- [self.constraints replaceObjectAtIndex:index withObject:replacementConstraint];
- }
- - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
- MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute];
- 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 {
- __unused MASAttribute anyAttribute = (MASAttributeLeft | MASAttributeRight | MASAttributeTop | MASAttributeBottom | MASAttributeLeading
- | MASAttributeTrailing | MASAttributeWidth | MASAttributeHeight | MASAttributeCenterX
- | MASAttributeCenterY | MASAttributeBaseline
- | MASAttributeFirstBaseline | MASAttributeLastBaseline
- #if TARGET_OS_IPHONE || TARGET_OS_TV
- | MASAttributeLeftMargin | MASAttributeRightMargin | MASAttributeTopMargin | MASAttributeBottomMargin
- | MASAttributeLeadingMargin | MASAttributeTrailingMargin | MASAttributeCenterXWithinMargins
- | MASAttributeCenterYWithinMargins
- #endif
- );
-
- 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];
- if (attrs & MASAttributeFirstBaseline) [attributes addObject:self.view.mas_firstBaseline];
- if (attrs & MASAttributeLastBaseline) [attributes addObject:self.view.mas_lastBaseline];
-
- #if TARGET_OS_IPHONE || TARGET_OS_TV
-
- if (attrs & MASAttributeLeftMargin) [attributes addObject:self.view.mas_leftMargin];
- if (attrs & MASAttributeRightMargin) [attributes addObject:self.view.mas_rightMargin];
- if (attrs & MASAttributeTopMargin) [attributes addObject:self.view.mas_topMargin];
- if (attrs & MASAttributeBottomMargin) [attributes addObject:self.view.mas_bottomMargin];
- if (attrs & MASAttributeLeadingMargin) [attributes addObject:self.view.mas_leadingMargin];
- if (attrs & MASAttributeTrailingMargin) [attributes addObject:self.view.mas_trailingMargin];
- if (attrs & MASAttributeCenterXWithinMargins) [attributes addObject:self.view.mas_centerXWithinMargins];
- if (attrs & MASAttributeCenterYWithinMargins) [attributes addObject:self.view.mas_centerYWithinMargins];
-
- #endif
-
- 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 *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
- return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute];
- }
- - (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];
- }
- - (MASConstraint *(^)(MASAttribute))attributes {
- return [^(MASAttribute attrs){
- return [self addConstraintWithAttributes:attrs];
- } copy];
- }
- - (MASConstraint *)firstBaseline {
- return [self addConstraintWithLayoutAttribute:NSLayoutAttributeFirstBaseline];
- }
- - (MASConstraint *)lastBaseline {
- return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLastBaseline];
- }
- #if TARGET_OS_IPHONE || TARGET_OS_TV
- - (MASConstraint *)leftMargin {
- return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin];
- }
- - (MASConstraint *)rightMargin {
- return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin];
- }
- - (MASConstraint *)topMargin {
- return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin];
- }
- - (MASConstraint *)bottomMargin {
- return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin];
- }
- - (MASConstraint *)leadingMargin {
- return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin];
- }
- - (MASConstraint *)trailingMargin {
- return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin];
- }
- - (MASConstraint *)centerXWithinMargins {
- return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins];
- }
- - (MASConstraint *)centerYWithinMargins {
- return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins];
- }
- #endif
- #pragma mark - composite Attributes
- - (MASConstraint *)edges {
- return [self addConstraintWithAttributes:MASAttributeTop | MASAttributeLeft | MASAttributeRight | MASAttributeBottom];
- }
- - (MASConstraint *)size {
- return [self addConstraintWithAttributes:MASAttributeWidth | MASAttributeHeight];
- }
- - (MASConstraint *)center {
- return [self addConstraintWithAttributes:MASAttributeCenterX | MASAttributeCenterY];
- }
- #pragma mark - grouping
- - (MASConstraint *(^)(dispatch_block_t group))group {
- return [^id(dispatch_block_t group) {
- NSInteger previousCount = self.constraints.count;
- group();
- NSArray *children = [self.constraints subarrayWithRange:NSMakeRange(previousCount, self.constraints.count - previousCount)];
- MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
- constraint.delegate = self;
- return constraint;
- } copy];
- }
- @end
|