Skip to content

Commit

Permalink
Merge pull request SnapKit#107 from kovpas/master
Browse files Browse the repository at this point in the history
Implemented support for new NSLayoutConstraint's active property
  • Loading branch information
cloudkite committed Jan 8, 2015
2 parents 230e222 + a870b52 commit 2c55faf
Show file tree
Hide file tree
Showing 18 changed files with 176 additions and 11 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
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
======

Expand Down
6 changes: 6 additions & 0 deletions Examples/Masonry iOS Examples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
114413091924B6EE008E702E /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 114413081924B6EE008E702E /* [email protected] */; };
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 */; };
Expand All @@ -33,6 +34,7 @@

/* Begin PBXFileReference section */
114413081924B6EE008E702E /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; 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>"; };
Expand Down Expand Up @@ -127,6 +129,7 @@
DD52F23A179CAD57005CD195 /* MASAppDelegate.m */,
DD52F257179CADCB005CD195 /* Controllers */,
DD52F256179CADC4005CD195 /* Views */,
3C02224819D0C4EC00507321 /* Images.xcassets */,
DD52F231179CAD57005CD195 /* Supporting Files */,
);
path = "Masonry iOS Examples";
Expand Down Expand Up @@ -239,6 +242,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3C02224919D0C4EC00507321 /* Images.xcassets in Resources */,
DD52F235179CAD57005CD195 /* InfoPlist.strings in Resources */,
114413091924B6EE008E702E /* [email protected] in Resources */,
);
Expand Down Expand Up @@ -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";
Expand All @@ -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";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"images" : [
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "[email protected]",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "667h",
"filename" : "[email protected]",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "retina4",
"filename" : "[email protected]",
"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" : "[email protected]",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"filename" : "[email protected]",
"subtype" : "retina4",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions Masonry.podspec
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
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' => '[email protected]' }
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.
Expand Down
12 changes: 12 additions & 0 deletions Masonry/MASCompositeConstraint.m
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,18 @@ - (void)setCenterOffset:(CGPoint)centerOffset {

#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;
Expand Down
15 changes: 13 additions & 2 deletions Masonry/MASConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -171,6 +171,17 @@
@property (nonatomic, copy, readonly) MASConstraint *animator;
#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.
*/
Expand Down
4 changes: 4 additions & 0 deletions Masonry/MASConstraint.m
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ - (MASConstraint *)animator { MASMethodNotImplemented(); }

#endif

- (void)activate { MASMethodNotImplemented(); }

- (void)deactivate { MASMethodNotImplemented(); }

- (void)install { MASMethodNotImplemented(); }

- (void)uninstall { MASMethodNotImplemented(); }
Expand Down
42 changes: 40 additions & 2 deletions Masonry/MASViewConstraint.m
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,21 @@ - (void)setLayoutRelation:(NSLayoutRelation)layoutRelation {
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 {
Expand Down Expand Up @@ -272,10 +285,34 @@ - (void)setCenterOffset:(CGPoint)centerOffset {

#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;
Expand Down Expand Up @@ -351,6 +388,7 @@ - (void)uninstall {
[self.installedView removeConstraint:self.layoutConstraint];
self.layoutConstraint = nil;
self.installedView = nil;

[self.firstViewAttribute.view.mas_installedConstraints removeObject:self];
}

Expand Down
8 changes: 4 additions & 4 deletions Masonry/NSLayoutConstraint+MASDebugAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ - (NSString *)description {
[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)];
}
}
Expand Down
20 changes: 20 additions & 0 deletions Tests/Specs/MASCompositeConstraintSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,26 @@ - (void)testUninstall {
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 = @[
Expand Down
2 changes: 1 addition & 1 deletion Tests/Specs/MASViewConstraintSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ - (void)testAttributeChainingShouldNotHaveRelation {
constraint.lessThanOrEqualTo(secondViewAttribute);

expect(^{
id result = constraint.bottom;
__unused id result = constraint.bottom;
}).to.raise(@"NSInternalInconsistencyException");
}

Expand Down

0 comments on commit 2c55faf

Please sign in to comment.