Authored by Jonas Budelmann

Merge pull request #62 from nickynick/equalTo-autoboxing

Autoboxing for scalar/struct attribute values
... ... @@ -35,11 +35,11 @@
make.right.equalTo(@-20);
}];
// auto-boxing macros allow you to simply use scalars and structs, they will be wrapped automatically
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(@50);
make.centerX.equalTo(@0);
make.width.equalTo(@200);
make.height.equalTo(@100);
make.center.equalTo(CGPointMake(0, 50));
make.size.equalTo(CGSizeMake(200, 100));
}];
return self;
... ...
... ... @@ -16,5 +16,8 @@
//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND
#import "Masonry.h"
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"
#endif
... ...
... ... @@ -14,6 +14,9 @@
location = "group:MASConstraint.m">
</FileRef>
<FileRef
location = "group:MASConstraint+Private.h">
</FileRef>
<FileRef
location = "group:MASCompositeConstraint.h">
</FileRef>
<FileRef
... ...
... ... @@ -7,6 +7,7 @@
//
#import "MASCompositeConstraint.h"
#import "MASConstraint+Private.h"
@interface MASCompositeConstraint () <MASConstraintDelegate>
... ... @@ -37,36 +38,6 @@
[self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint];
}
#pragma mark - NSLayoutConstraint constant proxies
- (MASConstraint * (^)(MASEdgeInsets))insets {
return ^id(MASEdgeInsets insets) {
self.insets = insets;
return self;
};
}
- (MASConstraint * (^)(CGFloat))offset {
return ^id(CGFloat offset) {
self.offset = offset;
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;
};
}
#pragma mark - NSLayoutConstraint multiplier proxies
- (MASConstraint * (^)(CGFloat))multipliedBy {
... ... @@ -87,7 +58,7 @@
};
}
#pragma mark - MASLayoutPriority proxies
#pragma mark - MASLayoutPriority proxy
- (MASConstraint * (^)(MASLayoutPriority))priority {
return ^id(MASLayoutPriority priority) {
... ... @@ -98,62 +69,17 @@
};
}
- (MASConstraint * (^)())priorityLow {
return ^id{
self.priority(MASLayoutPriorityDefaultLow);
return self;
};
}
#pragma mark - NSLayoutRelation proxy
- (MASConstraint * (^)())priorityMedium {
return ^id{
self.priority(MASLayoutPriorityDefaultMedium);
return self;
};
}
- (MASConstraint * (^)())priorityHigh {
return ^id{
self.priority(MASLayoutPriorityDefaultHigh);
return self;
};
}
#pragma mark - NSLayoutRelation proxies
- (MASConstraint * (^)(id))equalTo {
return ^id(id attr) {
for (MASConstraint *constraint in self.childConstraints.copy) {
constraint.equalTo(attr);
}
return self;
};
}
- (MASConstraint * (^)(id))greaterThanOrEqualTo {
return ^id(id attr) {
- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
return ^id(id attr, NSLayoutRelation relation) {
for (MASConstraint *constraint in self.childConstraints.copy) {
constraint.greaterThanOrEqualTo(attr);
constraint.equalToWithRelation(attr, relation);
}
return self;
};
}
- (MASConstraint * (^)(id))lessThanOrEqualTo {
return ^id(id attr) {
for (MASConstraint *constraint in self.childConstraints.copy) {
constraint.lessThanOrEqualTo(attr);
}
return self;
};
}
#pragma mark - Semantic properties
- (MASConstraint *)with {
return self;
}
#pragma mark - Animator proxy
#if TARGET_OS_MAC && !TARGET_OS_IPHONE
... ...
//
// MASConstraint+Private.h
// Masonry
//
// Created by Nick Tymchenko on 29/04/14.
// Copyright (c) 2014 cloudling. All rights reserved.
//
#import "MASConstraint.h"
@protocol MASConstraintDelegate;
@interface MASConstraint ()
/**
* Whether or not to check for an existing constraint instead of adding constraint
*/
@property (nonatomic, assign) BOOL updateExisting;
/**
* Usually MASConstraintMaker but could be a parent MASConstraint
*/
@property (nonatomic, weak) id<MASConstraintDelegate> delegate;
/**
* Based on a provided value type, is equal to calling:
* NSNumber - setOffset:
* NSValue with CGPoint - setPointOffset:
* NSValue with CGSize - setSizeOffset:
* NSValue with MASEdgeInsets - setInsets:
*/
- (void)setLayoutConstantWithValue:(NSValue *)value;
@end
@interface MASConstraint (Abstract)
/**
* Sets the constraint relation to given NSLayoutRelation
* returns a block which accepts one of the following:
* MASViewAttribute, UIView, NSValue, NSArray
* see readme for more details.
*/
- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation;
@end
@protocol MASConstraintDelegate <NSObject>
/**
* Notifies the delegate when the constraint needs to be replaced with another constraint. For example
* A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks
*/
- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint;
@end
\ No newline at end of file
... ...
... ... @@ -8,8 +8,6 @@
#import "MASUtilities.h"
@protocol MASConstraintDelegate;
/**
* Enables Constraints to be created with chainable syntax
* Constraint can represent single NSLayoutConstraint (MASViewConstraint)
... ... @@ -21,7 +19,7 @@
/**
* Modifies the NSLayoutConstraint constant,
* only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
* only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
* NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
*/
- (MASConstraint * (^)(MASEdgeInsets insets))insets;
... ... @@ -46,6 +44,11 @@
- (MASConstraint * (^)(CGFloat offset))offset;
/**
* Modifies the NSLayoutConstraint constant based on a value type
*/
- (MASConstraint * (^)(NSValue *value))valueOffset;
/**
* Sets the NSLayoutConstraint multiplier property
*/
- (MASConstraint * (^)(CGFloat multiplier))multipliedBy;
... ... @@ -78,7 +81,7 @@
/**
* Sets the constraint relation to NSLayoutRelationEqual
* returns a block which accepts one of the following:
* MASViewAttribute, UIView, NSNumber, NSArray
* MASViewAttribute, UIView, NSValue, NSArray
* see readme for more details.
*/
- (MASConstraint * (^)(id attr))equalTo;
... ... @@ -86,7 +89,7 @@
/**
* Sets the constraint relation to NSLayoutRelationGreaterThanOrEqual
* returns a block which accepts one of the following:
* MASViewAttribute, UIView, NSNumber, NSArray
* MASViewAttribute, UIView, NSValue, NSArray
* see readme for more details.
*/
- (MASConstraint * (^)(id attr))greaterThanOrEqualTo;
... ... @@ -94,13 +97,13 @@
/**
* Sets the constraint relation to NSLayoutRelationLessThanOrEqual
* returns a block which accepts one of the following:
* MASViewAttribute, UIView, NSNumber, NSArray
* MASViewAttribute, UIView, NSValue, NSArray
* see readme for more details.
*/
- (MASConstraint * (^)(id attr))lessThanOrEqualTo;
/**
* optional semantic property which has no effect but improves the readability of constraint
* Optional semantic property which has no effect but improves the readability of constraint
*/
- (MASConstraint *)with;
... ... @@ -150,16 +153,6 @@
#endif
/**
* Whether or not to check for an existing constraint instead of adding constraint
*/
@property (nonatomic, assign) BOOL updateExisting;
/**
* Usually MASConstraintMaker but could be a parent MASConstraint
*/
@property (nonatomic, weak) id<MASConstraintDelegate> delegate;
/**
* Creates a NSLayoutConstraint and adds it to the appropriate view.
*/
- (void)install;
... ... @@ -171,12 +164,44 @@
@end
@protocol MASConstraintDelegate <NSObject>
/**
* Notifies the delegate when the constraint needs to be replaced with another constraint. For example
* A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks
* Convenience auto-boxing macros for MASConstraint methods.
*
* Defining MAS_SHORTHAND_GLOBALS will turn on auto-boxing for default syntax.
* A potential drawback of this is that the unprefixed macros will appear in global scope.
*/
- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint;
#define mas_equalTo(...) equalTo(MASBoxValue((__VA_ARGS__)))
#define mas_greaterThanOrEqualTo(...) greaterThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
#define mas_lessThanOrEqualTo(...) lessThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
@end
#define mas_offset(...) valueOffset(MASBoxValue((__VA_ARGS__)))
#ifdef MAS_SHORTHAND_GLOBALS
#define equalTo(...) mas_equalTo(__VA_ARGS__)
#define greaterThanOrEqualTo(...) mas_greaterThanOrEqualTo(__VA_ARGS__)
#define lessThanOrEqualTo(...) mas_lessThanOrEqualTo(__VA_ARGS__)
#define offset(...) mas_offset(__VA_ARGS__)
#endif
@interface MASConstraint (AutoboxingSupport)
/**
* Aliases to corresponding relation methods (for shorthand macros)
* Also needed to aid autocompletion
*/
- (MASConstraint * (^)(id attr))mas_equalTo;
- (MASConstraint * (^)(id attr))mas_greaterThanOrEqualTo;
- (MASConstraint * (^)(id attr))mas_lessThanOrEqualTo;
/**
* A dummy method to aid autocompletion
*/
- (MASConstraint * (^)(id offset))mas_offset;
@end
\ No newline at end of file
... ...
... ... @@ -6,6 +6,7 @@
//
#import "MASConstraint.h"
#import "MASConstraint+Private.h"
#define methodNotImplemented() \
@throw [NSException exceptionWithName:NSInternalInconsistencyException \
... ... @@ -21,35 +22,147 @@
return [super init];
}
#pragma mark - Abstract
#pragma mark - NSLayoutRelation proxies
- (MASConstraint * (^)(MASEdgeInsets insets))insets { methodNotImplemented(); }
- (MASConstraint * (^)(id))equalTo {
return ^id(id attribute) {
return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
};
}
- (MASConstraint * (^)(CGSize offset))sizeOffset { methodNotImplemented(); }
- (MASConstraint * (^)(id))mas_equalTo {
return ^id(id attribute) {
return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
};
}
- (MASConstraint * (^)(CGPoint offset))centerOffset { methodNotImplemented(); }
- (MASConstraint * (^)(id))greaterThanOrEqualTo {
return ^id(id attribute) {
return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual);
};
}
- (MASConstraint * (^)(CGFloat offset))offset { methodNotImplemented(); }
- (MASConstraint * (^)(id))mas_greaterThanOrEqualTo {
return ^id(id attribute) {
return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual);
};
}
- (MASConstraint * (^)(CGFloat multiplier))multipliedBy { methodNotImplemented(); }
- (MASConstraint * (^)(id))lessThanOrEqualTo {
return ^id(id attribute) {
return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual);
};
}
- (MASConstraint * (^)(CGFloat divider))dividedBy { methodNotImplemented(); }
- (MASConstraint * (^)(id))mas_lessThanOrEqualTo {
return ^id(id attribute) {
return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual);
};
}
- (MASConstraint * (^)(MASLayoutPriority priority))priority { methodNotImplemented(); }
#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 * (^)())priorityLow { methodNotImplemented(); }
- (MASConstraint * (^)(id offset))mas_offset {
// Will never be called due to macro
return nil;
}
- (MASConstraint * (^)())priorityMedium { methodNotImplemented(); }
#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);
}
}
- (MASConstraint * (^)())priorityHigh { methodNotImplemented(); }
#pragma mark - Semantic properties
- (MASConstraint * (^)(id attr))equalTo { methodNotImplemented(); }
- (MASConstraint *)with {
return self;
}
- (MASConstraint * (^)(id attr))greaterThanOrEqualTo { methodNotImplemented(); }
#pragma mark - Abstract
- (MASConstraint * (^)(id attr))lessThanOrEqualTo { methodNotImplemented(); }
- (MASConstraint * (^)(CGFloat multiplier))multipliedBy { methodNotImplemented(); }
- (MASConstraint * (^)(CGFloat divider))dividedBy { methodNotImplemented(); }
- (MASConstraint * (^)(MASLayoutPriority priority))priority { methodNotImplemented(); }
- (MASConstraint *)with { methodNotImplemented(); }
- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { methodNotImplemented(); }
- (MASConstraint * (^)(id key))key { methodNotImplemented(); }
... ...
... ... @@ -9,6 +9,7 @@
#import "MASConstraintMaker.h"
#import "MASViewConstraint.h"
#import "MASCompositeConstraint.h"
#import "MASConstraint+Private.h"
#import "MASViewAttribute.h"
#import "View+MASAdditions.h"
... ...
... ... @@ -67,3 +67,70 @@
*/
#define MAS_NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger))
#define MAS_NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (MAS_NSUINT_BIT - howmuch)))
/**
* Given a scalar or struct value, wraps it in NSValue
* Based on EXPObjectify: https://github.com/specta/expecta
*/
static inline id _MASBoxValue(const char *type, ...) {
va_list v;
va_start(v, type);
id obj = nil;
if (strcmp(type, @encode(id)) == 0) {
id actual = va_arg(v, id);
obj = actual;
} else if (strcmp(type, @encode(CGPoint)) == 0) {
CGPoint actual = (CGPoint)va_arg(v, CGPoint);
obj = [NSValue value:&actual withObjCType:type];
} else if (strcmp(type, @encode(CGSize)) == 0) {
CGSize actual = (CGSize)va_arg(v, CGSize);
obj = [NSValue value:&actual withObjCType:type];
} else if (strcmp(type, @encode(MASEdgeInsets)) == 0) {
MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets);
obj = [NSValue value:&actual withObjCType:type];
} else if (strcmp(type, @encode(char)) == 0) {
char actual = (char)va_arg(v, int);
obj = [NSNumber numberWithChar:actual];
} else if(strcmp(type, @encode(_Bool)) == 0) {
_Static_assert(sizeof(_Bool) <= sizeof(int), "Expected _Bool to be subject to vararg type promotion");
_Bool actual = (_Bool)va_arg(v, int);
obj = [NSNumber numberWithBool:actual];
} else if (strcmp(type, @encode(double)) == 0) {
double actual = (double)va_arg(v, double);
obj = [NSNumber numberWithDouble:actual];
} else if (strcmp(type, @encode(float)) == 0) {
float actual = (float)va_arg(v, double);
obj = [NSNumber numberWithFloat:actual];
} else if (strcmp(type, @encode(int)) == 0) {
int actual = (int)va_arg(v, int);
obj = [NSNumber numberWithInt:actual];
} else if (strcmp(type, @encode(long)) == 0) {
long actual = (long)va_arg(v, long);
obj = [NSNumber numberWithLong:actual];
} else if (strcmp(type, @encode(long long)) == 0) {
long long actual = (long long)va_arg(v, long long);
obj = [NSNumber numberWithLongLong:actual];
} else if (strcmp(type, @encode(short)) == 0) {
short actual = (short)va_arg(v, int);
obj = [NSNumber numberWithShort:actual];
} else if (strcmp(type, @encode(unsigned char)) == 0) {
unsigned char actual = (unsigned char)va_arg(v, unsigned int);
obj = [NSNumber numberWithUnsignedChar:actual];
} else if (strcmp(type, @encode(unsigned int)) == 0) {
unsigned int actual = (int)va_arg(v, unsigned int);
obj = [NSNumber numberWithUnsignedInt:actual];
} else if (strcmp(type, @encode(unsigned long)) == 0) {
unsigned long actual = (unsigned long)va_arg(v, unsigned long);
obj = [NSNumber numberWithUnsignedLong:actual];
} else if (strcmp(type, @encode(unsigned long long)) == 0) {
unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long);
obj = [NSNumber numberWithUnsignedLongLong:actual];
} else if (strcmp(type, @encode(unsigned short)) == 0) {
unsigned short actual = (unsigned short)va_arg(v, unsigned int);
obj = [NSNumber numberWithUnsignedShort:actual];
}
va_end(v);
return obj;
}
#define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value))
... ...
... ... @@ -7,6 +7,7 @@
//
#import "MASViewConstraint.h"
#import "MASConstraint+Private.h"
#import "MASCompositeConstraint.h"
#import "MASLayoutConstraint.h"
#import "View+MASAdditions.h"
... ... @@ -106,9 +107,9 @@ static char kInstalledConstraintsKey;
}
- (void)setSecondViewAttribute:(id)secondViewAttribute {
if ([secondViewAttribute isKindOfClass:NSNumber.class]) {
self.layoutConstant = [secondViewAttribute doubleValue];
} else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) {
if ([secondViewAttribute isKindOfClass:NSValue.class]) {
[self setLayoutConstantWithValue:secondViewAttribute];
} else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) {
_secondViewAttribute = [[MASViewAttribute alloc] initWithView:secondViewAttribute layoutAttribute:self.firstViewAttribute.layoutAttribute];
} else if ([secondViewAttribute isKindOfClass:MASViewAttribute.class]) {
_secondViewAttribute = secondViewAttribute;
... ... @@ -117,36 +118,6 @@ static char kInstalledConstraintsKey;
}
}
#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;
};
}
#pragma mark - NSLayoutConstraint multiplier proxies
- (MASConstraint * (^)(CGFloat))multipliedBy {
... ... @@ -170,7 +141,7 @@ static char kInstalledConstraintsKey;
};
}
#pragma mark - MASLayoutPriority proxies
#pragma mark - MASLayoutPriority proxy
- (MASConstraint * (^)(MASLayoutPriority))priority {
return ^id(MASLayoutPriority priority) {
... ... @@ -182,31 +153,10 @@ static char kInstalledConstraintsKey;
};
}
- (MASConstraint * (^)())priorityLow {
return ^id{
self.priority(MASLayoutPriorityDefaultLow);
return self;
};
}
#pragma mark - NSLayoutRelation proxy
- (MASConstraint * (^)())priorityMedium {
return ^id{
self.priority(MASLayoutPriorityDefaultMedium);
return self;
};
}
- (MASConstraint * (^)())priorityHigh {
return ^id{
self.priority(MASLayoutPriorityDefaultHigh);
return self;
};
}
#pragma mark - NSLayoutRelation proxies
- (MASConstraint * (^)(id))equalityWithRelation:(NSLayoutRelation)relation {
return ^id(id attribute) {
- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
return ^id(id attribute, NSLayoutRelation relation) {
if ([attribute isKindOfClass:NSArray.class]) {
NSAssert(!self.hasLayoutRelation, @"Redefinition of constraint relation");
NSMutableArray *children = NSMutableArray.new;
... ... @@ -220,7 +170,7 @@ static char kInstalledConstraintsKey;
[self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint];
return compositeConstraint;
} else {
NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSNumber.class], @"Redefinition of constraint relation");
NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSValue.class], @"Redefinition of constraint relation");
self.layoutRelation = relation;
self.secondViewAttribute = attribute;
return self;
... ... @@ -228,24 +178,6 @@ static char kInstalledConstraintsKey;
};
}
- (MASConstraint * (^)(id))equalTo {
return [self equalityWithRelation:NSLayoutRelationEqual];
}
- (MASConstraint * (^)(id))greaterThanOrEqualTo {
return [self equalityWithRelation:NSLayoutRelationGreaterThanOrEqual];
}
- (MASConstraint * (^)(id))lessThanOrEqualTo {
return [self equalityWithRelation:NSLayoutRelationLessThanOrEqual];
}
#pragma mark - Semantic properties
- (MASConstraint *)with {
return self;
}
#pragma mark - Animator proxy
#if TARGET_OS_MAC && !TARGET_OS_IPHONE
... ...
... ... @@ -6,7 +6,7 @@
// Copyright (c) 2013 Jonas Budelmann. All rights reserved.
//
#import "MASConstraint.h"
#import "MASConstraint+Private.h"
@interface MASConstraintDelegateMock : NSObject <MASConstraintDelegate>
... ...
... ... @@ -9,6 +9,7 @@
#import "MASConstraintMaker.h"
#import "MASCompositeConstraint.h"
#import "MASViewConstraint.h"
#import "MASConstraint+Private.h"
@interface MASConstraintMaker () <MASConstraintDelegate>
... ...
... ... @@ -7,6 +7,7 @@
//
#import "MASViewConstraint.h"
#import "MASConstraint+Private.h"
#import "MASConstraint.h"
#import "View+MASAdditions.h"
#import "MASConstraintDelegateMock.h"
... ... @@ -114,6 +115,72 @@ SpecBegin(MASViewConstraint) {
expect(constraint.firstViewAttribute.layoutAttribute).to.equal(constraint.secondViewAttribute.layoutAttribute);
}
- (void)testRelationAcceptsNumber {
constraint.equalTo(@42);
expect(constraint.secondViewAttribute.view).to.beNil();
expect(constraint.layoutConstant).to.equal(42);
}
- (void)testRelationAcceptsValueWithCGPoint {
CGPoint point = CGPointMake(10, 20);
NSValue *value = [NSValue value:&point withObjCType:@encode(CGPoint)];
MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
centerX.equalTo(value);
expect(centerX.layoutConstant).to.equal(10);
MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
centerY.equalTo(value);
expect(centerY.layoutConstant).to.equal(20);
MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
width.equalTo(value);
expect(width.layoutConstant).to.equal(0);
}
- (void)testRelationAcceptsValueWithCGSize {
CGSize size = CGSizeMake(30, 40);
NSValue *value = [NSValue value:&size withObjCType:@encode(CGSize)];
MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
width.equalTo(value);
expect(width.layoutConstant).to.equal(30);
MASViewConstraint *height = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_height];
height.equalTo(value);
expect(height.layoutConstant).to.equal(40);
MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
centerX.equalTo(value);
expect(centerX.layoutConstant).to.equal(0);
}
- (void)testRelationAcceptsValueWithEdgeInsets {
MASEdgeInsets insets = (MASEdgeInsets){10, 20, 30, 40};
NSValue *value = [NSValue value:&insets withObjCType:@encode(MASEdgeInsets)];
MASViewConstraint *top = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_top];
top.equalTo(value);
expect(top.layoutConstant).to.equal(10);
MASViewConstraint *left = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_left];
left.equalTo(value);
expect(left.layoutConstant).to.equal(20);
MASViewConstraint *bottom = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_bottom];
bottom.equalTo(value);
expect(bottom.layoutConstant).to.equal(-30);
MASViewConstraint *right = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_right];
right.equalTo(value);
expect(right.layoutConstant).to.equal(-40);
MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
centerX.equalTo(value);
expect(centerX.layoutConstant).to.equal(0);
}
- (void)testRelationCreatesCompositeWithArrayOfViews {
NSArray *views = @[MAS_VIEW.new, MAS_VIEW.new, MAS_VIEW.new];
... ... @@ -157,6 +224,59 @@ SpecBegin(MASViewConstraint) {
}).to.raise(@"NSInternalInconsistencyException");
}
- (void)testRelationAcceptsAutoboxedScalar {
constraint.mas_equalTo(42);
expect(constraint.layoutConstant).to.equal(42);
}
- (void)testRelationAcceptsAutoboxedCGPoint {
MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
centerX.mas_equalTo(CGPointMake(10, 20));
expect(centerX.layoutConstant).to.equal(10);
MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
centerY.mas_equalTo(CGPointMake(10, 20));
expect(centerY.layoutConstant).to.equal(20);
}
- (void)testRelationAcceptsAutoboxedCGSize {
MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
width.mas_equalTo(CGSizeMake(30, 40));
expect(width.layoutConstant).to.equal(30);
MASViewConstraint *height = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_height];
height.mas_equalTo(CGSizeMake(30, 40));
expect(height.layoutConstant).to.equal(40);
}
- (void)testRelationAcceptsAutoboxedEdgeInsets {
MASEdgeInsets insets = (MASEdgeInsets){10, 20, 30, 40};
MASViewConstraint *top = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_top];
top.mas_equalTo(insets);
expect(top.layoutConstant).to.equal(10);
MASViewConstraint *left = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_left];
left.mas_equalTo(insets);
expect(left.layoutConstant).to.equal(20);
MASViewConstraint *bottom = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_bottom];
bottom.mas_equalTo(insets);
expect(bottom.layoutConstant).to.equal(-30);
MASViewConstraint *right = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_right];
right.mas_equalTo(insets);
expect(right.layoutConstant).to.equal(-40);
}
- (void)testRelationAutoboxingComplainsWithUnsupportedArgument {
expect(^{
constraint.mas_equalTo(@{});
}).to.raise(@"NSInternalInconsistencyException");
}
- (void)testPriorityHigh {
constraint.equalTo(otherView);
constraint.with.priorityHigh();
... ... @@ -273,6 +393,57 @@ SpecBegin(MASViewConstraint) {
expect(height.layoutConstant).to.equal(55);
}
- (void)testAutoboxedConstantUpdateOffset {
constraint.mas_offset(42);
expect(constraint.layoutConstant).to.equal(42);
}
- (void)testAutoboxedConstantUpdateSidesOffset {
MASEdgeInsets insets = (MASEdgeInsets){10, 20, 30, 40};
MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
centerY.mas_offset(insets);
expect(centerY.layoutConstant).to.equal(0);
MASViewConstraint *top = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_top];
top.mas_offset(insets);
expect(top.layoutConstant).to.equal(10);
MASViewConstraint *left = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_left];
left.mas_offset(insets);
expect(left.layoutConstant).to.equal(20);
MASViewConstraint *bottom = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_bottom];
bottom.mas_offset(insets);
expect(bottom.layoutConstant).to.equal(-30);
MASViewConstraint *right = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_right];
right.mas_offset(insets);
expect(right.layoutConstant).to.equal(-40);
}
- (void)testAutoboxedConstantUpdateCenterOffset {
MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
centerX.mas_offset(CGPointMake(-20, -10));
expect(centerX.layoutConstant).to.equal(-20);
MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
centerY.mas_offset(CGPointMake(-20, -10));
expect(centerY.layoutConstant).to.equal(-10);
}
- (void)testAutoboxedConstantUpdateSizeOffset {
MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
width.mas_offset(CGSizeMake(-40, 55));
expect(width.layoutConstant).to.equal(-40);
MASViewConstraint *height = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_height];
height.mas_offset(CGSizeMake(-40, 55));
expect(height.layoutConstant).to.equal(55);
}
- (void)testInstallLayoutConstraintOnCommit {
MASViewAttribute *secondViewAttribute = otherView.mas_height;
constraint.equalTo(secondViewAttribute);
... ... @@ -312,8 +483,7 @@ SpecBegin(MASViewConstraint) {
expect(superview.constraints[0]).to.beIdenticalTo(constraint.layoutConstraint);
}
- (void)testInstallSizeAsConstant {
- (void)testInstallWidthAsConstant {
constraint.equalTo(@10);
[constraint install];
... ...