Toggle navigation
Toggle navigation
This project
Loading...
Sign in
ios
/
Masonry
·
Commits
Go to a project
GitLab
Go to group
Project
Activity
Files
Commits
Pipelines
0
Builds
0
Graphs
Milestones
Issues
0
Merge Requests
0
Members
Labels
Wiki
Forks
Network
Create a new issue
Download as
Email Patches
Plain Diff
Browse Files
Authored by
Jonas Budelmann
12 years ago
Commit
96dcf6f296122d9d3a5160a38bea4ba36d3d4ab7
1 parent
606fe6b4
added ability to remove constraint. refactored child constraints
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
107 additions
and
46 deletions
Masonry/MASCompositeConstraint.m
Masonry/MASConstraint.h
Masonry/MASConstraintMaker.m
Masonry/MASViewConstraint.m
MasonryTests/MASCompositeConstraintSpec.m
MasonryTests/MASConstraintDelegateMock.m
MasonryTests/MASViewConstraintSpec.m
Masonry/MASCompositeConstraint.m
View file @
96dcf6f
...
...
@@ -76,8 +76,10 @@
#pragma mark - MASConstraintDelegate
-
(
void
)
addConstraint
:
(
id
<
MASConstraint
>
)
constraint
{
[
self
.
delegate
addConstraint
:
constraint
];
-
(
void
)
constraint
:
(
id
<
MASConstraint
>
)
constraint
shouldBeReplacedWithConstraint
:
(
id
<
MASConstraint
>
)
replacementConstraint
{
int
index
=
[
self
.
childConstraints
indexOfObject
:
constraint
];
NSAssert
(
index
!=
NSNotFound
,
@"Could not find constraint %@"
,
constraint
);
[
self
.
childConstraints
replaceObjectAtIndex
:
index
withObject
:
replacementConstraint
];
}
#pragma mark - NSLayoutConstraint constant proxies
...
...
@@ -165,7 +167,7 @@
-
(
id
<
MASConstraint
>
(
^
)(
id
))
equalTo
{
return
^
id
(
id
attr
)
{
for
(
id
<
MASConstraint
>
constraint
in
self
.
childConstraints
)
{
for
(
id
<
MASConstraint
>
constraint
in
self
.
childConstraints
.
copy
)
{
constraint
.
equalTo
(
attr
);
}
return
self
;
...
...
@@ -174,7 +176,7 @@
-
(
id
<
MASConstraint
>
(
^
)(
id
))
greaterThanOrEqualTo
{
return
^
id
(
id
attr
)
{
for
(
id
<
MASConstraint
>
constraint
in
self
.
childConstraints
)
{
for
(
id
<
MASConstraint
>
constraint
in
self
.
childConstraints
.
copy
)
{
constraint
.
greaterThanOrEqualTo
(
attr
);
}
return
self
;
...
...
@@ -183,7 +185,7 @@
-
(
id
<
MASConstraint
>
(
^
)(
id
))
lessThanOrEqualTo
{
return
^
id
(
id
attr
)
{
for
(
id
<
MASConstraint
>
constraint
in
self
.
childConstraints
)
{
for
(
id
<
MASConstraint
>
constraint
in
self
.
childConstraints
.
copy
)
{
constraint
.
lessThanOrEqualTo
(
attr
);
}
return
self
;
...
...
@@ -211,7 +213,16 @@
#pragma mark - MASConstraint
-
(
void
)
commit
{
-
(
void
)
installConstraint
{
for
(
id
<
MASConstraint
>
constraint
in
self
.
childConstraints
)
{
[
constraint
installConstraint
];
}
}
-
(
void
)
uninstallConstraint
{
for
(
id
<
MASConstraint
>
constraint
in
self
.
childConstraints
)
{
[
constraint
uninstallConstraint
];
}
}
@end
...
...
Masonry/MASConstraint.h
View file @
96dcf6f
...
...
@@ -111,19 +111,23 @@ typedef float MASLayoutPriority;
@property
(
nonatomic
,
copy
,
readonly
)
id
<
MASConstraint
>
(
^
key
)(
id
key
);
/**
* Creates a NSLayoutConstraint. The constraint is
add
ed to the first view or the or the closest common superview of the first and second view.
* Creates a NSLayoutConstraint. The constraint is
install
ed to the first view or the or the closest common superview of the first and second view.
*/
-
(
void
)
commit
;
-
(
void
)
installConstraint
;
/**
* Removes previously installed NSLayoutConstraint
*/
-
(
void
)
uninstallConstraint
;
@end
@protocol
MASConstraintDelegate
<
NSObject
>
/**
* Notifies the delegate when the constraint is has the minimum set of properties.
*
* @param constraint a constraint that has at least a NSLayoutRelation and view
* 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
)
addConstraint
:
(
id
<
MASConstraint
>
)
c
onstraint
;
-
(
void
)
constraint
:
(
id
<
MASConstraint
>
)
constraint
shouldBeReplacedWithConstraint
:
(
id
<
MASConstraint
>
)
replacementC
onstraint
;
@end
\ No newline at end of file
...
...
Masonry/MASConstraintMaker.m
View file @
96dcf6f
...
...
@@ -32,15 +32,17 @@
-
(
void
)
commit
{
for
(
id
<
MASConstraint
>
constraint
in
self
.
constraints
)
{
[
constraint
commi
t
];
[
constraint
installConstrain
t
];
}
[
self
.
constraints
removeAllObjects
];
}
#pragma mark - MASConstraintDelegate
-
(
void
)
addConstraint
:
(
id
<
MASConstraint
>
)
constraint
{
[
self
.
constraints
addObject
:
constraint
];
-
(
void
)
constraint
:
(
id
<
MASConstraint
>
)
constraint
shouldBeReplacedWithConstraint
:
(
id
<
MASConstraint
>
)
replacementConstraint
{
int
index
=
[
self
.
constraints
indexOfObject
:
constraint
];
NSAssert
(
index
!=
NSNotFound
,
@"Could not find constraint %@"
,
constraint
);
[
self
.
constraints
replaceObjectAtIndex
:
index
withObject
:
replacementConstraint
];
}
#pragma mark - constraint properties
...
...
@@ -49,6 +51,7 @@
MASViewAttribute
*
viewAttribute
=
[[
MASViewAttribute
alloc
]
initWithView
:
self
.
view
layoutAttribute
:
layoutAttribute
];
MASViewConstraint
*
constraint
=
[[
MASViewConstraint
alloc
]
initWithFirstViewAttribute
:
viewAttribute
];
constraint
.
delegate
=
self
;
[
self
.
constraints
addObject
:
constraint
];
return
constraint
;
}
...
...
@@ -104,18 +107,21 @@
-
(
id
<
MASConstraint
>
)
edges
{
MASCompositeConstraint
*
constraint
=
[[
MASCompositeConstraint
alloc
]
initWithView
:
self
.
view
type
:
MASCompositeConstraintTypeEdges
];
constraint
.
delegate
=
self
;
[
self
.
constraints
addObject
:
constraint
];
return
constraint
;
}
-
(
id
<
MASConstraint
>
)
size
{
MASCompositeConstraint
*
constraint
=
[[
MASCompositeConstraint
alloc
]
initWithView
:
self
.
view
type
:
MASCompositeConstraintTypeSize
];
constraint
.
delegate
=
self
;
[
self
.
constraints
addObject
:
constraint
];
return
constraint
;
}
-
(
id
<
MASConstraint
>
)
center
{
MASCompositeConstraint
*
constraint
=
[[
MASCompositeConstraint
alloc
]
initWithView
:
self
.
view
type
:
MASCompositeConstraintTypeCenter
];
constraint
.
delegate
=
self
;
[
self
.
constraints
addObject
:
constraint
];
return
constraint
;
}
@end
...
...
Masonry/MASViewConstraint.m
View file @
96dcf6f
...
...
@@ -14,6 +14,7 @@
@property
(
nonatomic
,
strong
,
readwrite
)
MASViewAttribute
*
secondViewAttribute
;
@property
(
nonatomic
,
strong
,
readwrite
)
MASLayoutConstraint
*
layoutConstraint
;
@property
(
nonatomic
,
weak
)
UIView
*
installedView
;
@property
(
nonatomic
,
assign
)
NSLayoutRelation
layoutRelation
;
@property
(
nonatomic
,
assign
)
MASLayoutPriority
layoutPriority
;
@property
(
nonatomic
,
assign
)
CGFloat
layoutMultiplier
;
...
...
@@ -60,7 +61,7 @@
self
.
hasLayoutRelation
=
YES
;
}
-
(
BOOL
)
hasBeen
Committ
ed
{
-
(
BOOL
)
hasBeen
Install
ed
{
return
self
.
layoutConstraint
!=
nil
;
}
...
...
@@ -146,8 +147,8 @@
-
(
id
<
MASConstraint
>
(
^
)(
CGFloat
))
percent
{
return
^
id
(
CGFloat
percent
)
{
NSAssert
(
!
self
.
hasBeenCommitted
,
@"Cannot modify constraint percent after it has been committed"
);
NSAssert
(
!
self
.
hasBeenInstalled
,
@"Cannot modify constraint percent after it has been installed"
);
self
.
layoutMultiplier
=
percent
;
return
self
;
...
...
@@ -158,8 +159,8 @@
-
(
id
<
MASConstraint
>
(
^
)(
MASLayoutPriority
))
priority
{
return
^
id
(
MASLayoutPriority
priority
)
{
NSAssert
(
!
self
.
hasBeenCommitted
,
@"Cannot modify constraint priority after it has been committed"
);
NSAssert
(
!
self
.
hasBeenInstalled
,
@"Cannot modify constraint priority after it has been installed"
);
self
.
layoutPriority
=
priority
;
return
self
;
...
...
@@ -197,16 +198,15 @@
for
(
id
attr
in
attribute
)
{
MASViewConstraint
*
viewConstraint
=
[
self
copy
];
viewConstraint
.
secondViewAttribute
=
attr
;
[
viewConstraint
.
delegate
addConstraint
:
viewConstraint
];
[
children
addObject
:
viewConstraint
];
}
MASCompositeConstraint
*
compositeConstraint
=
[[
MASCompositeConstraint
alloc
]
initWithView
:
self
.
firstViewAttribute
.
view
children
:
children
];
compositeConstraint
.
delegate
=
self
.
delegate
;
[
self
.
delegate
constraint
:
self
shouldBeReplacedWithConstraint
:
compositeConstraint
];
return
compositeConstraint
;
}
else
{
self
.
layoutRelation
=
relation
;
self
.
secondViewAttribute
=
attribute
;
[
self
.
delegate
addConstraint
:
self
];
return
self
;
}
};
...
...
@@ -241,8 +241,8 @@
#pragma mark - MASConstraint
-
(
void
)
commit
{
NSAssert
(
!
self
.
hasBeenCommitted
,
@"Cannot commit constraint more than once"
);
-
(
void
)
installConstraint
{
NSAssert
(
!
self
.
hasBeenInstalled
,
@"Cannot install constraint more than once"
);
UIView
*
firstLayoutItem
=
self
.
firstViewAttribute
.
view
;
NSLayoutAttribute
firstLayoutAttribute
=
self
.
firstViewAttribute
.
layoutAttribute
;
...
...
@@ -283,11 +283,18 @@
@"couldn't find a common superview for %@ and %@"
,
firstLayoutItem
,
secondLayoutItem
);
self
.
installedView
=
closestCommonSuperview
;
[
closestCommonSuperview
addConstraint
:
self
.
layoutConstraint
];
}
else
{
self
.
installedView
=
firstLayoutItem
;
[
firstLayoutItem
addConstraint
:
self
.
layoutConstraint
];
}
}
-
(
void
)
uninstallConstraint
{
[
self
.
installedView
removeConstraint
:
self
.
layoutConstraint
];
self
.
layoutConstraint
=
nil
;
self
.
installedView
=
nil
;
}
@end
...
...
MasonryTests/MASCompositeConstraintSpec.m
View file @
96dcf6f
...
...
@@ -116,7 +116,7 @@ it(@"should complete children", ^{
expect
(
viewConstraint
.
layoutPriority
).
to
.
equal
(
MASLayoutPriorityDefaultLow
);
});
it
(
@"should not remove on
commit
"
,
^
{
it
(
@"should not remove on
install
"
,
^
{
composite
=
[[
MASCompositeConstraint
alloc
]
initWithView
:
view
type
:
MASCompositeConstraintTypeSize
];
composite
.
delegate
=
delegate
;
UIView
*
newView
=
UIView
.
new
;
...
...
@@ -125,11 +125,22 @@ it(@"should not remove on commit", ^{
//first equality statement
composite
.
equalTo
(
newView
).
sizeOffset
(
CGSizeMake
(
90
,
30
));
[
composite
commi
t
];
[
composite
installConstrain
t
];
expect
(
composite
.
childConstraints
).
to
.
haveCountOf
(
2
);
expect
(
delegate
.
constraints
).
to
.
contain
(
composite
.
childConstraints
[
0
]);
expect
(
delegate
.
constraints
).
to
.
contain
(
composite
.
childConstraints
[
1
]);
});
it
(
@"should spawn child composite constraints"
,
^
{
composite
=
[[
MASCompositeConstraint
alloc
]
initWithView
:
view
type
:
MASCompositeConstraintTypeSize
];
composite
.
delegate
=
delegate
;
UIView
*
otherView
=
UIView
.
new
;
[
superview
addSubview
:
otherView
];
composite
.
lessThanOrEqualTo
(@[
@2
,
otherView
]);
expect
(
composite
.
childConstraints
).
to
.
haveCountOf
(
2
);
expect
(
composite
.
childConstraints
[
0
]).
to
.
beKindOf
(
MASCompositeConstraint
.
class
);
expect
(
composite
.
childConstraints
[
1
]).
to
.
beKindOf
(
MASCompositeConstraint
.
class
);
});
SpecEnd
\ No newline at end of file
...
...
MasonryTests/MASConstraintDelegateMock.m
View file @
96dcf6f
...
...
@@ -19,8 +19,8 @@
return
self
;
}
-
(
void
)
addConstraint
:
(
id
<
MASConstraint
>
)
constraint
{
[
self
.
constraints
addObject
:
constraint
];
-
(
void
)
constraint
:
(
id
<
MASConstraint
>
)
constraint
shouldBeReplacedWithConstraint
:
(
id
<
MASConstraint
>
)
replacementConstraint
{
[
self
.
constraints
replaceObjectAtIndex
:[
self
.
constraints
indexOfObject
:
constraint
]
withObject
:
replacementConstraint
];
}
@end
...
...
MasonryTests/MASViewConstraintSpec.m
View file @
96dcf6f
...
...
@@ -10,6 +10,7 @@
#import "MASConstraint.h"
#import "UIView+MASAdditions.h"
#import "MASConstraintDelegateMock.h"
#import "MASCompositeConstraint.h"
@interface
MASViewConstraint
()
...
...
@@ -21,6 +22,12 @@
@end
@interface
MASCompositeConstraint
()
<
MASConstraintDelegate
>
@property
(
nonatomic
,
strong
)
NSMutableArray
*
childConstraints
;
@end
SpecBegin
(
MASViewConstraint
)
__block
MASConstraintDelegateMock
*
delegate
;
...
...
@@ -49,7 +56,6 @@ describe(@"create equality constraint", ^{
MASViewAttribute
*
secondViewAttribute
=
otherView
.
mas_top
;
MASViewConstraint
*
newConstraint
=
(
id
)
constraint
.
equalTo
(
secondViewAttribute
);
expect
(
delegate
.
constraints
).
to
.
contain
(
constraint
);
expect
(
newConstraint
).
to
.
beIdenticalTo
(
constraint
);
expect
(
constraint
.
secondViewAttribute
).
to
.
beIdenticalTo
(
secondViewAttribute
);
expect
(
constraint
.
layoutRelation
).
to
.
equal
(
NSLayoutRelationEqual
);
...
...
@@ -59,7 +65,6 @@ describe(@"create equality constraint", ^{
MASViewAttribute
*
secondViewAttribute
=
otherView
.
mas_top
;
MASViewConstraint
*
newConstraint
=
(
id
)
constraint
.
greaterThanOrEqualTo
(
secondViewAttribute
);
expect
(
delegate
.
constraints
).
to
.
contain
(
constraint
);
expect
(
newConstraint
).
to
.
beIdenticalTo
(
constraint
);
expect
(
constraint
.
secondViewAttribute
).
to
.
beIdenticalTo
(
secondViewAttribute
);
expect
(
constraint
.
layoutRelation
).
to
.
equal
(
NSLayoutRelationGreaterThanOrEqual
);
...
...
@@ -69,7 +74,6 @@ describe(@"create equality constraint", ^{
MASViewAttribute
*
secondViewAttribute
=
otherView
.
mas_top
;
MASViewConstraint
*
newConstraint
=
(
id
)
constraint
.
lessThanOrEqualTo
(
secondViewAttribute
);
expect
(
delegate
.
constraints
).
to
.
contain
(
constraint
);
expect
(
newConstraint
).
to
.
beIdenticalTo
(
constraint
);
expect
(
constraint
.
secondViewAttribute
).
to
.
beIdenticalTo
(
secondViewAttribute
);
expect
(
constraint
.
layoutRelation
).
to
.
equal
(
NSLayoutRelationLessThanOrEqual
);
...
...
@@ -112,11 +116,14 @@ describe(@"create equality constraint", ^{
it
(
@"should create composite when passed array of views"
,
^
{
NSArray
*
views
=
@[
UIView
.
new
,
UIView
.
new
,
UIView
.
new
];
constraint
.
equalTo
(
views
).
priorityMedium
().
offset
(
-
10
);
[
delegate
.
constraints
addObject
:
constraint
];
MASCompositeConstraint
*
composite
=
(
id
)
constraint
.
equalTo
(
views
).
priorityMedium
().
offset
(
-
10
);
expect
(
delegate
.
constraints
).
to
.
haveCountOf
(
3
);
for
(
MASViewConstraint
*
constraint
in
delegate
.
constraints
)
{
int
index
=
[
delegate
.
constraints
indexOfObject
:
constraint
];
expect
(
delegate
.
constraints
).
to
.
haveCountOf
(
1
);
expect
(
delegate
.
constraints
[
0
]).
to
.
beKindOf
(
MASCompositeConstraint
.
class
);
for
(
MASViewConstraint
*
constraint
in
composite
.
childConstraints
)
{
int
index
=
[
composite
.
childConstraints
indexOfObject
:
constraint
];
expect
(
constraint
.
secondViewAttribute
.
view
).
to
.
beIdenticalTo
(
views
[
index
]);
expect
(
constraint
.
firstViewAttribute
.
layoutAttribute
).
to
.
equal
(
NSLayoutAttributeWidth
);
expect
(
constraint
.
secondViewAttribute
.
layoutAttribute
).
to
.
equal
(
NSLayoutAttributeWidth
);
...
...
@@ -127,11 +134,14 @@ describe(@"create equality constraint", ^{
it
(
@"should create composite when passed array of attributes"
,
^
{
NSArray
*
viewAttributes
=
@[
UIView
.
new
.
mas_height
,
UIView
.
new
.
mas_left
];
constraint
.
equalTo
(
viewAttributes
).
priority
(
60
).
offset
(
10
);
[
delegate
.
constraints
addObject
:
constraint
];
MASCompositeConstraint
*
composite
=
(
id
)
constraint
.
equalTo
(
viewAttributes
).
priority
(
60
).
offset
(
10
);
expect
(
delegate
.
constraints
).
to
.
haveCountOf
(
2
);
for
(
MASViewConstraint
*
constraint
in
delegate
.
constraints
)
{
int
index
=
[
delegate
.
constraints
indexOfObject
:
constraint
];
expect
(
delegate
.
constraints
).
to
.
haveCountOf
(
1
);
expect
(
delegate
.
constraints
[
0
]).
to
.
beKindOf
(
MASCompositeConstraint
.
class
);
for
(
MASViewConstraint
*
constraint
in
composite
.
childConstraints
)
{
int
index
=
[
composite
.
childConstraints
indexOfObject
:
constraint
];
expect
(
constraint
.
secondViewAttribute
.
view
).
to
.
beIdenticalTo
([
viewAttributes
[
index
]
view
]);
expect
(
constraint
.
firstViewAttribute
.
layoutAttribute
).
to
.
equal
(
NSLayoutAttributeWidth
);
expect
(
constraint
.
secondViewAttribute
.
layoutAttribute
).
to
.
equal
([
viewAttributes
[
index
]
layoutAttribute
]);
...
...
@@ -144,7 +154,7 @@ describe(@"create equality constraint", ^{
describe
(
@"multiplier & constant"
,
^
{
it
(
@"should not allow update of multiplier after layoutconstraint is created"
,
^
{
[
constraint
commi
t
];
[
constraint
installConstrain
t
];
expect
(
^
{
constraint
.
percent
(
0
.
9
);
...
...
@@ -152,7 +162,7 @@ describe(@"multiplier & constant", ^{
});
it
(
@"should allow update of constant after layoutconstraint is created"
,
^
{
[
constraint
commi
t
];
[
constraint
installConstrain
t
];
constraint
.
offset
(
10
);
expect
(
constraint
.
layoutConstant
).
to
.
equal
(
10
);
...
...
@@ -210,7 +220,7 @@ describe(@"multiplier & constant", ^{
});
});
describe
(
@"
commit
"
,
^
{
describe
(
@"
install
"
,
^
{
it
(
@"should create layout constraint on commit"
,
^
{
MASViewAttribute
*
secondViewAttribute
=
otherView
.
mas_height
;
...
...
@@ -218,7 +228,7 @@ describe(@"commit", ^{
constraint
.
percent
(
0
.
5
);
constraint
.
offset
(
10
);
constraint
.
priority
(
345
);
[
constraint
commi
t
];
[
constraint
installConstrain
t
];
expect
(
constraint
.
layoutConstraint
.
firstAttribute
).
to
.
equal
(
NSLayoutAttributeWidth
);
expect
(
constraint
.
layoutConstraint
.
secondAttribute
).
to
.
equal
(
NSLayoutAttributeHeight
);
...
...
@@ -232,6 +242,18 @@ describe(@"commit", ^{
expect
(
superview
.
constraints
[
0
]).
to
.
beIdenticalTo
(
constraint
.
layoutConstraint
);
});
it
(
@"should uninstall constraint"
,
^
{
MASViewAttribute
*
secondViewAttribute
=
otherView
.
mas_height
;
constraint
.
equalTo
(
secondViewAttribute
);
[
constraint
installConstraint
];
expect
(
superview
.
constraints
).
to
.
haveCountOf
(
1
);
expect
(
superview
.
constraints
[
0
]).
to
.
equal
(
constraint
.
layoutConstraint
);
[
constraint
uninstallConstraint
];
expect
(
superview
.
constraints
).
to
.
haveCountOf
(
0
);
});
});
SpecEnd
\ No newline at end of file
...
...
Please
register
or
login
to post a comment