Authored by Jonas Budelmann

Merge pull request #107 from kovpas/master

Implemented support for new NSLayoutConstraint's active property
v0.6.0
======
#### - Improved support of iOS 8
As of iOS 8 there is `active` property of `NSLayoutConstraint` available, which allows to (de)activate constraint without searching closest common superview.
#### - Added support of iPhone 6 and iPhone 6+ to test project
v0.5.3
======
... ...
... ... @@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
114413091924B6EE008E702E /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 114413081924B6EE008E702E /* Default-568h@2x.png */; };
3C02224919D0C4EC00507321 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3C02224819D0C4EC00507321 /* Images.xcassets */; };
3DB1CAD5184538E200E91FC5 /* MASExampleArrayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB1CAD4184538E200E91FC5 /* MASExampleArrayView.m */; };
4BEB55B61957394E008C862B /* MASExampleRemakeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BEB55B51957394E008C862B /* MASExampleRemakeView.m */; };
6C87DADA5AB046D9A3181A65 /* libPods-Masonry iOS Examples.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BDC1B8303EED42A2B01B94B1 /* libPods-Masonry iOS Examples.a */; };
... ... @@ -33,6 +34,7 @@
/* Begin PBXFileReference section */
114413081924B6EE008E702E /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
3C02224819D0C4EC00507321 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
3DB1CAD3184538E200E91FC5 /* MASExampleArrayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASExampleArrayView.h; sourceTree = "<group>"; };
3DB1CAD4184538E200E91FC5 /* MASExampleArrayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASExampleArrayView.m; sourceTree = "<group>"; };
4BEB55B41957394E008C862B /* MASExampleRemakeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASExampleRemakeView.h; sourceTree = "<group>"; };
... ... @@ -127,6 +129,7 @@
DD52F23A179CAD57005CD195 /* MASAppDelegate.m */,
DD52F257179CADCB005CD195 /* Controllers */,
DD52F256179CADC4005CD195 /* Views */,
3C02224819D0C4EC00507321 /* Images.xcassets */,
DD52F231179CAD57005CD195 /* Supporting Files */,
);
path = "Masonry iOS Examples";
... ... @@ -239,6 +242,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3C02224919D0C4EC00507321 /* Images.xcassets in Resources */,
DD52F235179CAD57005CD195 /* InfoPlist.strings in Resources */,
114413091924B6EE008E702E /* Default-568h@2x.png in Resources */,
);
... ... @@ -379,6 +383,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = B086DD7D31DD4B49ADC08504 /* Pods-Masonry iOS Examples.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Masonry iOS Examples/Masonry iOS Examples-Prefix.pch";
INFOPLIST_FILE = "Masonry iOS Examples/Masonry iOS Examples-Info.plist";
... ... @@ -391,6 +396,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = B086DD7D31DD4B49ADC08504 /* Pods-Masonry iOS Examples.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Masonry iOS Examples/Masonry iOS Examples-Prefix.pch";
INFOPLIST_FILE = "Masonry iOS Examples/Masonry iOS Examples-Info.plist";
... ...
{
"images" : [
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "Default-736h@3x.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "667h",
"filename" : "Default-667h@2x.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"filename" : "Default@2x.png",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "retina4",
"filename" : "Default-568h@2x.png",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"filename" : "Default_iOS6.png",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"filename" : "Default_iOS6@2x.png",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"filename" : "Default_iOS6-568h@2x.png",
"subtype" : "retina4",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ...
Pod::Spec.new do |s|
s.name = 'Masonry'
s.version = '0.5.3'
s.version = '0.6.0'
s.license = 'MIT'
s.summary = 'Harness the power of Auto Layout NSLayoutConstraints with a simplified, chainable and expressive syntax.'
s.homepage = 'https://github.com/cloudkite/Masonry'
s.author = { 'Jonas Budelmann' => 'jonas.budelmann@gmail.com' }
s.social_media_url = "http://twitter.com/cloudkite"
s.source = { :git => 'https://github.com/cloudkite/Masonry.git', :tag => 'v0.5.3' }
s.source = { :git => 'https://github.com/cloudkite/Masonry.git', :tag => 'v0.6.0' }
s.description = %{
Masonry is a light-weight layout framework which wraps AutoLayout with a nicer syntax.
... ...
... ... @@ -149,6 +149,18 @@
#pragma mark - MASConstraint
- (void)activate {
for (MASConstraint *constraint in self.childConstraints) {
[constraint activate];
}
}
- (void)deactivate {
for (MASConstraint *constraint in self.childConstraints) {
[constraint deactivate];
}
}
- (void)install {
for (MASConstraint *constraint in self.childConstraints) {
constraint.updateExisting = self.updateExisting;
... ...
... ... @@ -108,12 +108,12 @@
- (MASConstraint *)with;
/**
* 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 *)and;
/**
* creates a new MASCompositeConstraint with the called attribute and reciever
* Creates a new MASCompositeConstraint with the called attribute and reciever
*/
- (MASConstraint *)left;
- (MASConstraint *)top;
... ... @@ -172,6 +172,17 @@
#endif
/**
* Activates an NSLayoutConstraint if it's supported by an OS.
* Invokes install otherwise.
*/
- (void)activate;
/**
* Deactivates previously installed/activated NSLayoutConstraint.
*/
- (void)deactivate;
/**
* Creates a NSLayoutConstraint and adds it to the appropriate view.
*/
- (void)install;
... ...
... ... @@ -234,6 +234,10 @@
#endif
- (void)activate { MASMethodNotImplemented(); }
- (void)deactivate { MASMethodNotImplemented(); }
- (void)install { MASMethodNotImplemented(); }
- (void)uninstall { MASMethodNotImplemented(); }
... ...
... ... @@ -102,8 +102,21 @@ static char kInstalledConstraintsKey;
self.hasLayoutRelation = YES;
}
- (BOOL)supportsActiveProperty {
return [self.layoutConstraint respondsToSelector:@selector(isActive)];
}
- (BOOL)isActive {
BOOL active = YES;
if ([self supportsActiveProperty]) {
active = [self.layoutConstraint isActive];
}
return active;
}
- (BOOL)hasBeenInstalled {
return self.layoutConstraint != nil;
return (self.layoutConstraint != nil) && [self isActive];
}
- (void)setSecondViewAttribute:(id)secondViewAttribute {
... ... @@ -272,10 +285,34 @@ static char kInstalledConstraintsKey;
#pragma mark - MASConstraint
- (void)activate {
if ([self supportsActiveProperty] && self.layoutConstraint) {
if (self.hasBeenInstalled) {
return;
}
self.layoutConstraint.active = YES;
[self.firstViewAttribute.view.mas_installedConstraints addObject:self];
} else {
[self install];
}
}
- (void)deactivate {
if ([self.layoutConstraint respondsToSelector:@selector(setActive:)]) {
self.layoutConstraint.active = NO;
[self.firstViewAttribute.view.mas_installedConstraints removeObject:self];
} else {
[self uninstall];
}
}
- (void)install {
NSAssert(!self.hasBeenInstalled, @"Cannot install constraint more than once");
if (self.hasBeenInstalled) {
return;
}
MAS_VIEW *firstLayoutItem = self.firstViewAttribute.view;
NSLayoutAttribute firstLayoutAttribute = self.firstViewAttribute.layoutAttribute;
MAS_VIEW *secondLayoutItem = self.secondViewAttribute.view;
NSLayoutAttribute secondLayoutAttribute = self.secondViewAttribute.layoutAttribute;
... ... @@ -351,6 +388,7 @@ static char kInstalledConstraintsKey;
[self.installedView removeConstraint:self.layoutConstraint];
self.layoutConstraint = nil;
self.installedView = nil;
[self.firstViewAttribute.view.mas_installedConstraints removeObject:self];
}
... ...
... ... @@ -110,10 +110,10 @@
[description appendFormat:@" * %g", self.multiplier];
}
if (self.constant) {
if (self.secondAttribute == NSLayoutAttributeNotAnAttribute) {
[description appendFormat:@" %g", self.constant];
} else {
if (self.secondAttribute == NSLayoutAttributeNotAnAttribute) {
[description appendFormat:@" %g", self.constant];
} else {
if (self.constant) {
[description appendFormat:@" %@ %g", (self.constant < 0 ? @"-" : @"+"), ABS(self.constant)];
}
}
... ...
... ... @@ -152,6 +152,26 @@ SpecBegin(MASCompositeConstraint) {
expect(superview.constraints).to.haveCountOf(0);
}
- (void)testActivateDeactivate {
NSArray *children = @[
[[MASViewConstraint alloc] initWithFirstViewAttribute:view.mas_leading],
[[MASViewConstraint alloc] initWithFirstViewAttribute:view.mas_trailing]
];
composite = [[MASCompositeConstraint alloc] initWithChildren:children];
composite.delegate = delegate;
MAS_VIEW *newView = MAS_VIEW.new;
[superview addSubview:newView];
//first equality statement
composite.equalTo(newView);
[composite install];
expect(superview.constraints).to.haveCountOf(2);
[composite deactivate];
expect(superview.constraints).to.haveCountOf(0);
[composite activate];
expect(superview.constraints).to.haveCountOf(2);
}
- (void)testAttributeChainingShouldCallDelegate {
NSArray *children = @[
... ...
... ... @@ -514,7 +514,7 @@ SpecBegin(MASViewConstraint) {
constraint.lessThanOrEqualTo(secondViewAttribute);
expect(^{
id result = constraint.bottom;
__unused id result = constraint.bottom;
}).to.raise(@"NSInternalInconsistencyException");
}
... ...