| // | 
| //  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 * (^)())priorityLow { | 
|     return ^id{ | 
|         self.priority(MASLayoutPriorityDefaultLow); | 
|         return self; | 
|     }; | 
| } | 
|   | 
| - (MASConstraint * (^)())priorityMedium { | 
|     return ^id{ | 
|         self.priority(MASLayoutPriorityDefaultMedium); | 
|         return self; | 
|     }; | 
| } | 
|   | 
| - (MASConstraint * (^)())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 * (^)(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 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 - 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)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 |