Skip to content

Commit b7b9271

Browse files
authored
Merge pull request #278 from corujautx/master
Minor improvements and fixes to Cartography
2 parents 340cd25 + 69c4968 commit b7b9271

File tree

10 files changed

+425
-117
lines changed

10 files changed

+425
-117
lines changed

Cartography.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22

33
s.name = "Cartography"
4-
s.version = "3.0.0"
4+
s.version = "3.0.1"
55
s.summary = "Declarative Auto Layout in Swift"
66

77
s.description = <<-DESC
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
1313
s.author = { "Robert Böhnke" => "[email protected]" }
1414

1515
s.ios.deployment_target = "8.0"
16-
s.osx.deployment_target = "10.9"
16+
s.osx.deployment_target = "10.10"
1717
s.tvos.deployment_target = "9.0"
1818

1919
s.source = { :git => "https://github.com/robb/Cartography.git", :tag => s.version }

Cartography.xcodeproj/project.pbxproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
977C36821F9FAC890057A057 /* AutoresizingMaskLayoutProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977C36811F9FAC890057A057 /* AutoresizingMaskLayoutProxy.swift */; };
9090
977C36831F9FC2900057A057 /* AutoresizingMaskLayoutProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977C36811F9FAC890057A057 /* AutoresizingMaskLayoutProxy.swift */; };
9191
977C36841F9FC2910057A057 /* AutoresizingMaskLayoutProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977C36811F9FAC890057A057 /* AutoresizingMaskLayoutProxy.swift */; };
92+
97885B1E1FC4F7C800BB4E51 /* LayoutGuideSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979F29C91F94DC6B00257363 /* LayoutGuideSpec.swift */; };
9293
979558E41F9700B40096BBEA /* LayoutGuideSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979F29C91F94DC6B00257363 /* LayoutGuideSpec.swift */; };
9394
979558EC1F97015E0096BBEA /* TestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D17C9E1F8E774700C57CE1 /* TestView.swift */; };
9495
979558ED1F97015E0096BBEA /* TestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D17C9E1F8E774700C57CE1 /* TestView.swift */; };
@@ -138,8 +139,8 @@
138139
97D17CAC1F8E779300C57CE1 /* LayoutGuideProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D17CA91F8E779300C57CE1 /* LayoutGuideProxy.swift */; };
139140
97E7F0A91F8D598A004857CE /* ViewProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97E7F0A81F8D598A004857CE /* ViewProxy.swift */; };
140141
97F50E521F962CF300C6DCF5 /* LayoutProxy+TypeErasure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F50E511F962CF300C6DCF5 /* LayoutProxy+TypeErasure.swift */; };
141-
97F50E541F9633AA00C6DCF5 /* SafeAreaLayoutGuideSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F50E531F9633AA00C6DCF5 /* SafeAreaLayoutGuideSpec.swift */; };
142-
97F50E551F9633AA00C6DCF5 /* SafeAreaLayoutGuideSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F50E531F9633AA00C6DCF5 /* SafeAreaLayoutGuideSpec.swift */; };
142+
97F50E541F9633AA00C6DCF5 /* ViewLayoutGuideSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F50E531F9633AA00C6DCF5 /* ViewLayoutGuideSpec.swift */; };
143+
97F50E551F9633AA00C6DCF5 /* ViewLayoutGuideSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F50E531F9633AA00C6DCF5 /* ViewLayoutGuideSpec.swift */; };
143144
97F50E561F96401200C6DCF5 /* LayoutProxy+TypeErasure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F50E511F962CF300C6DCF5 /* LayoutProxy+TypeErasure.swift */; };
144145
97F50E571F96401300C6DCF5 /* LayoutProxy+TypeErasure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F50E511F962CF300C6DCF5 /* LayoutProxy+TypeErasure.swift */; };
145146
A75B6143FF12C54FF3223B47 /* Pods_TestPods_Cartography_tvOS_tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0827A83361EACF1E6062607E /* Pods_TestPods_Cartography_tvOS_tests.framework */; };
@@ -259,7 +260,6 @@
259260
97D17C9F1F8E774700C57CE1 /* Matchers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Matchers.swift; sourceTree = "<group>"; };
260261
97D17CA01F8E774700C57CE1 /* DistributeSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DistributeSpec.swift; sourceTree = "<group>"; };
261262
97D17CA11F8E774700C57CE1 /* PointSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointSpec.swift; sourceTree = "<group>"; };
262-
97D17CA21F8E774700C57CE1 /* EdgesSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EdgesSpec.swift; sourceTree = "<group>"; };
263263
97D17CA31F8E774700C57CE1 /* ViewHierarchySpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewHierarchySpec.swift; sourceTree = "<group>"; };
264264
97D17CA41F8E774700C57CE1 /* DimensionSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DimensionSpec.swift; sourceTree = "<group>"; };
265265
97D17CA51F8E774700C57CE1 /* MemoryLeakSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryLeakSpec.swift; sourceTree = "<group>"; };
@@ -268,7 +268,7 @@
268268
97D17CA91F8E779300C57CE1 /* LayoutGuideProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutGuideProxy.swift; sourceTree = "<group>"; };
269269
97E7F0A81F8D598A004857CE /* ViewProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewProxy.swift; sourceTree = "<group>"; };
270270
97F50E511F962CF300C6DCF5 /* LayoutProxy+TypeErasure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LayoutProxy+TypeErasure.swift"; sourceTree = "<group>"; };
271-
97F50E531F9633AA00C6DCF5 /* SafeAreaLayoutGuideSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafeAreaLayoutGuideSpec.swift; sourceTree = "<group>"; };
271+
97F50E531F9633AA00C6DCF5 /* ViewLayoutGuideSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewLayoutGuideSpec.swift; sourceTree = "<group>"; };
272272
EE85314F1F9363DC003EC021 /* LayoutItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutItem.swift; sourceTree = "<group>"; };
273273
EEDD4098FF7503B1F9188F10 /* Pods_Cartography_iOS_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Cartography_iOS_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
274274
/* End PBXFileReference section */
@@ -467,13 +467,12 @@
467467
97D17C9F1F8E774700C57CE1 /* Matchers.swift */,
468468
97D17CA01F8E774700C57CE1 /* DistributeSpec.swift */,
469469
97D17CA11F8E774700C57CE1 /* PointSpec.swift */,
470-
97D17CA21F8E774700C57CE1 /* EdgesSpec.swift */,
471470
97D17CA31F8E774700C57CE1 /* ViewHierarchySpec.swift */,
472471
97D17CA41F8E774700C57CE1 /* DimensionSpec.swift */,
473472
97D17CA51F8E774700C57CE1 /* MemoryLeakSpec.swift */,
474473
97D17CA61F8E774700C57CE1 /* ConstraintGroupSpec.swift */,
475474
97D17CA81F8E774700C57CE1 /* SizeSpec.swift */,
476-
97F50E531F9633AA00C6DCF5 /* SafeAreaLayoutGuideSpec.swift */,
475+
97F50E531F9633AA00C6DCF5 /* ViewLayoutGuideSpec.swift */,
477476
);
478477
path = CartographyTests;
479478
sourceTree = SOURCE_ROOT;
@@ -935,7 +934,7 @@
935934
buildActionMask = 2147483647;
936935
files = (
937936
979558F61F97017D0096BBEA /* LayoutSupportSpec.swift in Sources */,
938-
97F50E541F9633AA00C6DCF5 /* SafeAreaLayoutGuideSpec.swift in Sources */,
937+
97F50E541F9633AA00C6DCF5 /* ViewLayoutGuideSpec.swift in Sources */,
939938
9795590B1F9701CD0096BBEA /* ConstraintGroupSpec.swift in Sources */,
940939
979559081F9701C90096BBEA /* MemoryLeakSpec.swift in Sources */,
941940
979558FC1F97019E0096BBEA /* Matchers.swift in Sources */,
@@ -1000,6 +999,7 @@
1000999
9795590C1F9701CE0096BBEA /* ConstraintGroupSpec.swift in Sources */,
10011000
979559061F9701BC0096BBEA /* ViewHierarchySpec.swift in Sources */,
10021001
979558F91F9701860096BBEA /* PrioritySpec.swift in Sources */,
1002+
97885B1E1FC4F7C800BB4E51 /* LayoutGuideSpec.swift in Sources */,
10031003
979558F21F97016C0096BBEA /* EdgesSpec.swift in Sources */,
10041004
979558ED1F97015E0096BBEA /* TestView.swift in Sources */,
10051005
979559091F9701C90096BBEA /* MemoryLeakSpec.swift in Sources */,
@@ -1045,7 +1045,7 @@
10451045
buildActionMask = 2147483647;
10461046
files = (
10471047
979558F71F97017F0096BBEA /* LayoutSupportSpec.swift in Sources */,
1048-
97F50E551F9633AA00C6DCF5 /* SafeAreaLayoutGuideSpec.swift in Sources */,
1048+
97F50E551F9633AA00C6DCF5 /* ViewLayoutGuideSpec.swift in Sources */,
10491049
9795590D1F9701CF0096BBEA /* ConstraintGroupSpec.swift in Sources */,
10501050
9795590A1F9701CA0096BBEA /* MemoryLeakSpec.swift in Sources */,
10511051
979558FD1F9701A10096BBEA /* Matchers.swift in Sources */,

Cartography/Edges.swift

Lines changed: 125 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,106 @@ public struct Edges: Compound, RelativeCompoundEquality, RelativeCompoundInequal
1717
public let properties: [Property]
1818

1919
internal init(_ context: Context, _ properties: [Property]) {
20+
guard properties.count == 4 else {
21+
fatalError("No valid edges were used")
22+
}
23+
2024
self.context = context
2125
self.properties = properties
2226
}
27+
28+
/// Insets all edges individually.
29+
///
30+
/// - parameter top: The amount by which to inset the top edge, in points.
31+
/// - parameter leading: The amount by which to inset the leading edge, in points.
32+
/// - parameter bottom: The amount by which to inset the bottom edge, in points.
33+
/// - parameter trailing: The amount by which to inset the trailing edge, in points.
34+
///
35+
/// - returns: A new expression with the inseted edges.
36+
///
37+
public func inseted(top: CGFloat, leading: CGFloat, bottom: CGFloat, trailing: CGFloat) -> Expression<Edges> {
38+
return Expression(
39+
self,
40+
[
41+
Coefficients(1, top),
42+
Coefficients(1, leading),
43+
Coefficients(1, -bottom),
44+
Coefficients(1, -trailing)
45+
]
46+
)
47+
}
48+
49+
/// Insets all horizontal and vertical edges.
50+
///
51+
/// - parameter horizontally: The amount by which to inset the leading and trailing edges, in points.
52+
/// - parameter vertically: The amount by which to inset the top and bottom edges, in points.
53+
///
54+
/// - returns: A new expression with the inseted edges.
55+
///
56+
public func inseted(horizontally: CGFloat, vertically: CGFloat) -> Expression<Edges> {
57+
return self.inseted(
58+
top: vertically,
59+
leading: horizontally,
60+
bottom: vertically,
61+
trailing: horizontally
62+
)
63+
}
64+
65+
/// Insets all horizontal edges.
66+
///
67+
/// - parameter horizontally: The amount by which to inset the leading and trailing edges, in points.
68+
///
69+
/// - returns: A new expression with the inseted edges.
70+
///
71+
public func inseted(horizontally: CGFloat) -> Expression<Edges> {
72+
return self.inseted(
73+
horizontally: horizontally,
74+
vertically: 0
75+
)
76+
}
77+
78+
/// Insets all vertical edges.
79+
///
80+
/// - parameter vertically: The amount by which to inset the top and bottom edges, in points.
81+
///
82+
/// - returns: A new expression with the inseted edges.
83+
///
84+
public func inseted(vertically: CGFloat) -> Expression<Edges> {
85+
return self.inseted(
86+
horizontally: 0,
87+
vertically: vertically
88+
)
89+
}
90+
91+
/// Insets all edges by a single value.
92+
///
93+
/// - parameter by: The amount by which to inset the top and bottom edges, in points.
94+
///
95+
/// - returns: A new expression with the inseted edges.
96+
///
97+
public func inseted(by value: CGFloat) -> Expression<Edges> {
98+
return self.inseted(
99+
horizontally: value,
100+
vertically: value
101+
)
102+
}
103+
104+
#if os(iOS) || os(tvOS)
105+
/// Insets all edges individually using an existing UIEdgeInsets.
106+
///
107+
/// - parameter by: The UIEdgeInsets to use as a base value.
108+
///
109+
/// - returns: A new expression with the inseted edges.
110+
///
111+
public func inseted(by insets: UIEdgeInsets) -> Expression<Edges> {
112+
return self.inseted(
113+
top: insets.top,
114+
leading: insets.left,
115+
bottom: insets.bottom,
116+
trailing: insets.right
117+
)
118+
}
119+
#endif
23120
}
24121

25122
/// Insets all edges.
@@ -30,7 +127,7 @@ public struct Edges: Compound, RelativeCompoundEquality, RelativeCompoundInequal
30127
/// - returns: A new expression with the inset edges.
31128
///
32129
public func inset(_ edges: Edges, _ all: CGFloat) -> Expression<Edges> {
33-
return inset(edges, all, all, all, all)
130+
return edges.inseted(by: all)
34131
}
35132

36133
/// Insets the horizontal and vertical edges.
@@ -44,7 +141,31 @@ public func inset(_ edges: Edges, _ all: CGFloat) -> Expression<Edges> {
44141
/// - returns: A new expression with the inset edges.
45142
///
46143
public func inset(_ edges: Edges, _ horizontal: CGFloat, _ vertical: CGFloat) -> Expression<Edges> {
47-
return inset(edges, vertical, horizontal, vertical, horizontal)
144+
return edges.inseted(horizontally: horizontal, vertically: vertical)
145+
}
146+
147+
/// Insets the horizontal edges.
148+
///
149+
/// - parameter edges: The edges to inset.
150+
/// - parameter horizontally: The amount by which to inset the horizontal edges, in
151+
/// points.
152+
///
153+
/// - returns: A new expression with the inset edges.
154+
///
155+
public func inset(_ edges: Edges, horizontally horizontal: CGFloat) -> Expression<Edges> {
156+
return edges.inseted(horizontally: horizontal)
157+
}
158+
159+
/// Insets the vertical edges.
160+
///
161+
/// - parameter edges: The edges to inset.
162+
/// - parameter vertically: The amount by which to inset the vertical edges, in
163+
/// points.
164+
///
165+
/// - returns: A new expression with the inset edges.
166+
///
167+
public func inset(_ edges: Edges, vertically vertical: CGFloat) -> Expression<Edges> {
168+
return edges.inseted(vertically: vertical)
48169
}
49170

50171
/// Insets edges individually.
@@ -58,12 +179,7 @@ public func inset(_ edges: Edges, _ horizontal: CGFloat, _ vertical: CGFloat) ->
58179
/// - returns: A new expression with the inset edges.
59180
///
60181
public func inset(_ edges: Edges, _ top: CGFloat, _ leading: CGFloat, _ bottom: CGFloat, _ trailing: CGFloat) -> Expression<Edges> {
61-
return Expression(edges, [
62-
Coefficients(1, top),
63-
Coefficients(1, leading),
64-
Coefficients(1, -bottom),
65-
Coefficients(1, -trailing)
66-
])
182+
return edges.inseted(top: top, leading: leading, bottom: bottom, trailing: trailing)
67183
}
68184

69185
#if os(iOS) || os(tvOS)
@@ -75,6 +191,6 @@ public func inset(_ edges: Edges, _ top: CGFloat, _ leading: CGFloat, _ bottom:
75191
/// - returns: A new expression with the inset edges.
76192
///
77193
public func inset(_ edges: Edges, _ insets: UIEdgeInsets) -> Expression<Edges> {
78-
return inset(edges, insets.top, insets.left, insets.bottom, insets.right)
194+
return edges.inseted(by: insets)
79195
}
80196
#endif

Cartography/LayoutGuide.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#if os(iOS) || os(tvOS)
1010
import UIKit
1111

12+
@available(iOS, introduced: 9.0)
13+
@available(tvOS, introduced: 9.0)
14+
public typealias LayoutGuide = UILayoutGuide
15+
1216
@available(iOS, introduced: 9.0)
1317
@available(tvOS, introduced: 9.0)
1418
extension UILayoutGuide: LayoutItem {
@@ -19,4 +23,18 @@ extension UILayoutGuide: LayoutItem {
1923
return LayoutGuideProxy(context: context, item: self)
2024
}
2125
}
26+
#elseif os(OSX)
27+
import AppKit
28+
29+
@available(OSX, introduced: 10.11)
30+
public typealias LayoutGuide = NSLayoutGuide
31+
32+
@available(OSX, introduced: 10.11)
33+
extension NSLayoutGuide: LayoutItem {
34+
35+
@available(OSX, introduced: 10.11)
36+
public func asProxy(context: Context) -> LayoutGuideProxy {
37+
return LayoutGuideProxy(context: context, item: self)
38+
}
39+
}
2240
#endif

Cartography/LayoutGuideProxy.swift

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,18 @@
66
// Copyright © 2017 Robert Böhnke. All rights reserved.
77
//
88

9-
#if os(iOS) || os(tvOS)
10-
import UIKit
11-
129
@available(iOS, introduced: 9.0)
1310
@available(tvOS, introduced: 9.0)
11+
@available(OSX, introduced: 10.11)
1412
public final class LayoutGuideProxy: SupportsPositioningLayoutProxy {
1513
public let context: Context
1614

17-
private let layoutGuide: UILayoutGuide
15+
private let layoutGuide: LayoutGuide
1816
public var item: AnyObject {
1917
return layoutGuide
2018
}
2119

22-
public init(context: Context, item: UILayoutGuide) {
20+
public init(context: Context, item: LayoutGuide) {
2321
self.context = context
2422
self.layoutGuide = item
2523
}
@@ -28,4 +26,3 @@ public final class LayoutGuideProxy: SupportsPositioningLayoutProxy {
2826
return layoutGuide.owningView?.asProxy(context: context)
2927
}
3028
}
31-
#endif

Cartography/ViewProxy.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,17 @@ public final class ViewProxy: SupportsPositioningLayoutProxy, SupportsBaselineLa
3838
public var safeAreaLayoutGuide: LayoutGuideProxy {
3939
return view.safeAreaLayoutGuide.asProxy(context: context)
4040
}
41+
42+
@available(iOS, introduced: 9.0)
43+
@available(tvOS, introduced: 9.0)
44+
public var layoutMarginsGuide: LayoutGuideProxy {
45+
return view.layoutMarginsGuide.asProxy(context: context)
46+
}
47+
48+
@available(iOS, introduced: 9.0)
49+
@available(tvOS, introduced: 9.0)
50+
public var readableContentGuide: LayoutGuideProxy {
51+
return view.readableContentGuide.asProxy(context: context)
52+
}
4153
#endif
4254
}

CartographyTests/EdgesSpec.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ class EdgesSpec: QuickSpec {
6161
expect(view.frame).to(equal(CGRect(x: 20, y: 30, width: 360, height: 340)))
6262
}
6363

64+
it("should inset the horizontal edges") {
65+
constrain(view) { view in
66+
view.edges == inset(view.superview!.edges, horizontally: 20)
67+
}
68+
69+
window.layoutIfNeeded()
70+
71+
expect(view.frame).to(equal(CGRect(x: 20, y: 0, width: 360, height: 400)))
72+
}
73+
74+
it("should inset the vertical edges") {
75+
constrain(view) { view in
76+
view.edges == inset(view.superview!.edges, vertically: 30)
77+
}
78+
79+
window.layoutIfNeeded()
80+
81+
expect(view.frame).to(equal(CGRect(x: 0, y: 30, width: 400, height: 340)))
82+
}
83+
6484
it("should inset all edges individually") {
6585
constrain(view) { view in
6686
view.edges == inset(view.superview!.edges, 10, 20, 30, 40)

0 commit comments

Comments
 (0)