New file |
| | |
| | | // |
| | | // 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 |
| | | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) |
| | | | MASAttributeFirstBaseline | MASAttributeLastBaseline |
| | | #endif |
| | | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) |
| | | | 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 (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) |
| | | |
| | | if (attrs & MASAttributeFirstBaseline) [attributes addObject:self.view.mas_firstBaseline]; |
| | | if (attrs & MASAttributeLastBaseline) [attributes addObject:self.view.mas_lastBaseline]; |
| | | |
| | | #endif |
| | | |
| | | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) |
| | | |
| | | 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]; |
| | | }; |
| | | } |
| | | |
| | | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) |
| | | |
| | | - (MASConstraint *)firstBaseline { |
| | | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeFirstBaseline]; |
| | | } |
| | | |
| | | - (MASConstraint *)lastBaseline { |
| | | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLastBaseline]; |
| | | } |
| | | |
| | | #endif |
| | | |
| | | |
| | | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) |
| | | |
| | | - (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; |
| | | }; |
| | | } |
| | | |
| | | @end |