New file |
| | |
| | | // |
| | | // MASConstraint.m |
| | | // Masonry |
| | | // |
| | | // Created by Nick Tymchenko on 1/20/14. |
| | | // |
| | | |
| | | #import "MASConstraint.h" |
| | | #import "MASConstraint+Private.h" |
| | | |
| | | #define MASMethodNotImplemented() \ |
| | | @throw [NSException exceptionWithName:NSInternalInconsistencyException \ |
| | | reason:[NSString stringWithFormat:@"You must override %@ in a subclass.", NSStringFromSelector(_cmd)] \ |
| | | userInfo:nil] |
| | | |
| | | @implementation MASConstraint |
| | | |
| | | #pragma mark - Init |
| | | |
| | | - (id)init { |
| | | NSAssert(![self isMemberOfClass:[MASConstraint class]], @"MASConstraint is an abstract class, you should not instantiate it directly."); |
| | | return [super init]; |
| | | } |
| | | |
| | | #pragma mark - NSLayoutRelation proxies |
| | | |
| | | - (MASConstraint * (^)(id))equalTo { |
| | | return ^id(id attribute) { |
| | | return self.equalToWithRelation(attribute, NSLayoutRelationEqual); |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(id))mas_equalTo { |
| | | return ^id(id attribute) { |
| | | return self.equalToWithRelation(attribute, NSLayoutRelationEqual); |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(id))greaterThanOrEqualTo { |
| | | return ^id(id attribute) { |
| | | return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual); |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(id))mas_greaterThanOrEqualTo { |
| | | return ^id(id attribute) { |
| | | return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual); |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(id))lessThanOrEqualTo { |
| | | return ^id(id attribute) { |
| | | return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual); |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(id))mas_lessThanOrEqualTo { |
| | | return ^id(id attribute) { |
| | | return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual); |
| | | }; |
| | | } |
| | | |
| | | #pragma mark - MASLayoutPriority proxies |
| | | |
| | | - (MASConstraint * (^)(void))priorityLow { |
| | | return ^id{ |
| | | self.priority(MASLayoutPriorityDefaultLow); |
| | | return self; |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(void))priorityMedium { |
| | | return ^id{ |
| | | self.priority(MASLayoutPriorityDefaultMedium); |
| | | return self; |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(void))priorityHigh { |
| | | return ^id{ |
| | | self.priority(MASLayoutPriorityDefaultHigh); |
| | | return self; |
| | | }; |
| | | } |
| | | |
| | | #pragma mark - NSLayoutConstraint constant proxies |
| | | |
| | | - (MASConstraint * (^)(MASEdgeInsets))insets { |
| | | return ^id(MASEdgeInsets insets){ |
| | | self.insets = insets; |
| | | return self; |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(CGFloat))inset { |
| | | return ^id(CGFloat inset){ |
| | | self.inset = inset; |
| | | return self; |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(CGSize))sizeOffset { |
| | | return ^id(CGSize offset) { |
| | | self.sizeOffset = offset; |
| | | return self; |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(CGPoint))centerOffset { |
| | | return ^id(CGPoint offset) { |
| | | self.centerOffset = offset; |
| | | return self; |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(CGFloat))offset { |
| | | return ^id(CGFloat offset){ |
| | | self.offset = offset; |
| | | return self; |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(NSValue *value))valueOffset { |
| | | return ^id(NSValue *offset) { |
| | | NSAssert([offset isKindOfClass:NSValue.class], @"expected an NSValue offset, got: %@", offset); |
| | | [self setLayoutConstantWithValue:offset]; |
| | | return self; |
| | | }; |
| | | } |
| | | |
| | | - (MASConstraint * (^)(id offset))mas_offset { |
| | | // Will never be called due to macro |
| | | return nil; |
| | | } |
| | | |
| | | #pragma mark - NSLayoutConstraint constant setter |
| | | |
| | | - (void)setLayoutConstantWithValue:(NSValue *)value { |
| | | if ([value isKindOfClass:NSNumber.class]) { |
| | | self.offset = [(NSNumber *)value doubleValue]; |
| | | } else if (strcmp(value.objCType, @encode(CGPoint)) == 0) { |
| | | CGPoint point; |
| | | [value getValue:&point]; |
| | | self.centerOffset = point; |
| | | } else if (strcmp(value.objCType, @encode(CGSize)) == 0) { |
| | | CGSize size; |
| | | [value getValue:&size]; |
| | | self.sizeOffset = size; |
| | | } else if (strcmp(value.objCType, @encode(MASEdgeInsets)) == 0) { |
| | | MASEdgeInsets insets; |
| | | [value getValue:&insets]; |
| | | self.insets = insets; |
| | | } else { |
| | | NSAssert(NO, @"attempting to set layout constant with unsupported value: %@", value); |
| | | } |
| | | } |
| | | |
| | | #pragma mark - Semantic properties |
| | | |
| | | - (MASConstraint *)with { |
| | | return self; |
| | | } |
| | | |
| | | - (MASConstraint *)and { |
| | | return self; |
| | | } |
| | | |
| | | #pragma mark - Chaining |
| | | |
| | | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute __unused)layoutAttribute { |
| | | MASMethodNotImplemented(); |
| | | } |
| | | |
| | | - (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]; |
| | | } |
| | | |
| | | #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 - Abstract |
| | | |
| | | - (MASConstraint * (^)(CGFloat multiplier))multipliedBy { MASMethodNotImplemented(); } |
| | | |
| | | - (MASConstraint * (^)(CGFloat divider))dividedBy { MASMethodNotImplemented(); } |
| | | |
| | | - (MASConstraint * (^)(MASLayoutPriority priority))priority { MASMethodNotImplemented(); } |
| | | |
| | | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { MASMethodNotImplemented(); } |
| | | |
| | | - (MASConstraint * (^)(id key))key { MASMethodNotImplemented(); } |
| | | |
| | | - (void)setInsets:(MASEdgeInsets __unused)insets { MASMethodNotImplemented(); } |
| | | |
| | | - (void)setInset:(CGFloat __unused)inset { MASMethodNotImplemented(); } |
| | | |
| | | - (void)setSizeOffset:(CGSize __unused)sizeOffset { MASMethodNotImplemented(); } |
| | | |
| | | - (void)setCenterOffset:(CGPoint __unused)centerOffset { MASMethodNotImplemented(); } |
| | | |
| | | - (void)setOffset:(CGFloat __unused)offset { MASMethodNotImplemented(); } |
| | | |
| | | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) |
| | | |
| | | - (MASConstraint *)animator { MASMethodNotImplemented(); } |
| | | |
| | | #endif |
| | | |
| | | - (void)activate { MASMethodNotImplemented(); } |
| | | |
| | | - (void)deactivate { MASMethodNotImplemented(); } |
| | | |
| | | - (void)install { MASMethodNotImplemented(); } |
| | | |
| | | - (void)uninstall { MASMethodNotImplemented(); } |
| | | |
| | | @end |