From 7b74047efb2952aa1af457278be551e134f882d3 Mon Sep 17 00:00:00 2001
From: Luc Dion
Date: Fri, 25 May 2018 20:35:09 -0400
Subject: [PATCH 001/389] Add Objective-C support for macOS
Plus:
* Removed not needed @discardableResult
---
PinLayout.xcodeproj/project.pbxproj | 8 +
Podfile.lock | 4 +-
Sources/Impl/PinLayoutImpl+Layouting.swift | 1 -
Sources/Impl/PinLayoutImpl+Relative.swift | 65 +--
Sources/Impl/PinLayoutImpl+Warning.swift | 1 -
Sources/Impl/PinLayoutImpl.swift | 268 +++-------
Sources/Impl/PinSafeArea.swift | 1 -
Sources/Impl/TypesImpl.swift | 1 -
Sources/NSView+PinLayout.swift | 6 +
Sources/ObjectiveC/PinLayoutObjC.swift | 130 +++--
Sources/ObjectiveC/PinLayoutObjCImpl.swift | 540 ++++++++++-----------
Sources/UIView+PinLayout.swift | 5 +
12 files changed, 467 insertions(+), 563 deletions(-)
diff --git a/PinLayout.xcodeproj/project.pbxproj b/PinLayout.xcodeproj/project.pbxproj
index d82f6417..4dcefc0d 100644
--- a/PinLayout.xcodeproj/project.pbxproj
+++ b/PinLayout.xcodeproj/project.pbxproj
@@ -102,6 +102,10 @@
DFED1552208533DA009EF9A7 /* AspectRatioTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 248E4C721F7A83FA00C0E7F7 /* AspectRatioTests.swift */; };
DFED15532085349A009EF9A7 /* RectNimbleMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C5031E75DB7600073BEE /* RectNimbleMatcher.swift */; };
DFED15542085349B009EF9A7 /* RectNimbleMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C5031E75DB7600073BEE /* RectNimbleMatcher.swift */; };
+ DFF222B120B877F400AC2A84 /* PinLayoutObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 241A277B1F8E958F00B1AD39 /* PinLayoutObjC.swift */; };
+ DFF222B220B877F600AC2A84 /* PinLayoutObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 241A277B1F8E958F00B1AD39 /* PinLayoutObjC.swift */; };
+ DFF222B320B877F800AC2A84 /* PinLayoutObjCImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 241A277C1F8E958F00B1AD39 /* PinLayoutObjCImpl.swift */; };
+ DFF222B420B877F900AC2A84 /* PinLayoutObjCImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 241A277C1F8E958F00B1AD39 /* PinLayoutObjCImpl.swift */; };
DFF6F9C72084DCD3004F5AED /* PinLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 244DF2F81EF46C500090508B /* PinLayout.framework */; };
DFF6F9CD2084E15A004F5AED /* BasicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C5011E75D88500073BEE /* BasicView.swift */; };
DFF6F9CE2084E15A004F5AED /* AdjustSizeSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C4FF1E75D74000073BEE /* AdjustSizeSpec.swift */; };
@@ -787,6 +791,8 @@
buildActionMask = 2147483647;
files = (
243C62081FC37F6C0082C327 /* PinLayoutImpl+Warning.swift in Sources */,
+ DFF222B420B877F900AC2A84 /* PinLayoutObjCImpl.swift in Sources */,
+ DFF222B220B877F600AC2A84 /* PinLayoutObjC.swift in Sources */,
24D18D261F3E5EA5008129EF /* Pin.swift in Sources */,
DF1A5D362084CFC100725EF5 /* NSView+PinLayout.swift in Sources */,
243C62041FC37F680082C327 /* PinLayoutImpl.swift in Sources */,
@@ -885,6 +891,8 @@
buildActionMask = 2147483647;
files = (
DF1A5D3F2084CFD600725EF5 /* PinLayoutImpl+Warning.swift in Sources */,
+ DFF222B320B877F800AC2A84 /* PinLayoutObjCImpl.swift in Sources */,
+ DFF222B120B877F400AC2A84 /* PinLayoutObjC.swift in Sources */,
DF1A5D3B2084CFD600725EF5 /* PinLayoutImpl.swift in Sources */,
DF1A5D412084CFD600725EF5 /* Coordinates.swift in Sources */,
DF1A5D422084CFD600725EF5 /* Percent.swift in Sources */,
diff --git a/Podfile.lock b/Podfile.lock
index 108e8cc1..d8eb96e6 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -1,6 +1,6 @@
PODS:
- Nimble (7.0.3)
- - PinLayout (1.7.0)
+ - PinLayout (1.7.3)
- Quick (1.2.0)
- Reveal-SDK (10)
- SwiftLint (0.25.1)
@@ -25,7 +25,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
Nimble: 7f5a9c447a33002645a071bddafbfb24ea70e0ac
- PinLayout: 816805698a6c478d5f0cf97dd298243c098d6e50
+ PinLayout: 04488e8fc8d19b59760bdf99a16deff7bfac422d
Quick: 58d203b1c5e27fff7229c4c1ae445ad7069a7a08
Reveal-SDK: 7869ddf1f902cabbb07a1f0dd06bd25861a126f7
SwiftLint: ce933681be10c3266e82576dad676fa815a602e9
diff --git a/Sources/Impl/PinLayoutImpl+Layouting.swift b/Sources/Impl/PinLayoutImpl+Layouting.swift
index 1204a848..405bae96 100644
--- a/Sources/Impl/PinLayoutImpl+Layouting.swift
+++ b/Sources/Impl/PinLayoutImpl+Layouting.swift
@@ -443,4 +443,3 @@ extension PinLayoutImpl {
return view.isLTR()
}
}
-
diff --git a/Sources/Impl/PinLayoutImpl+Relative.swift b/Sources/Impl/PinLayoutImpl+Relative.swift
index 4005b304..f30d9852 100644
--- a/Sources/Impl/PinLayoutImpl+Relative.swift
+++ b/Sources/Impl/PinLayoutImpl+Relative.swift
@@ -28,25 +28,21 @@ extension PinLayoutImpl {
//
// above(of ...)
//
- @discardableResult
func above(of relativeView: PView) -> PinLayout {
func context() -> String { return "above(of: \(relativeView))" }
return above(relativeViews: [relativeView], aligned: nil, context: context)
}
-
- @discardableResult
+
func above(of relativeViews: [PView]) -> PinLayout {
func context() -> String { return "above(of: \(relativeViews))" }
return above(relativeViews: relativeViews, aligned: nil, context: context)
}
-
- @discardableResult
+
func above(of relativeView: PView, aligned: HorizontalAlign) -> PinLayout {
func context() -> String { return "above(of: \(relativeView), aligned: \(aligned))" }
return above(relativeViews: [relativeView], aligned: aligned, context: context)
}
-
- @discardableResult
+
func above(of relativeViews: [PView], aligned: HorizontalAlign) -> PinLayout {
func context() -> String { return "above(of: \(relativeViews), aligned: \(aligned))" }
return above(relativeViews: relativeViews, aligned: aligned, context: context)
@@ -55,25 +51,21 @@ extension PinLayoutImpl {
//
// below(of ...)
//
- @discardableResult
func below(of relativeView: PView) -> PinLayout {
func context() -> String { return "below(of: \(relativeView))" }
return below(relativeViews: [relativeView], aligned: nil, context: context)
}
-
- @discardableResult
+
func below(of relativeViews: [PView]) -> PinLayout {
func context() -> String { return "below(of: \(relativeViews))" }
return below(relativeViews: relativeViews, aligned: nil, context: context)
}
-
- @discardableResult
+
func below(of relativeView: PView, aligned: HorizontalAlign) -> PinLayout {
func context() -> String { return "below(of: \(relativeView), aligned: \(aligned))" }
return below(relativeViews: [relativeView], aligned: aligned, context: context)
}
-
- @discardableResult
+
func below(of relativeViews: [PView], aligned: HorizontalAlign) -> PinLayout {
func context() -> String { return "below(of: \(relativeViews), aligned: \(aligned))" }
return below(relativeViews: relativeViews, aligned: aligned, context: context)
@@ -82,25 +74,21 @@ extension PinLayoutImpl {
//
// left(of ...)
//
- @discardableResult
func left(of relativeView: PView) -> PinLayout {
func context() -> String { return "left(of: \(relativeView))" }
return left(relativeViews: [relativeView], aligned: nil, context: context)
}
-
- @discardableResult
+
func left(of relativeViews: [PView]) -> PinLayout {
func context() -> String { return "left(of: \(relativeViews))" }
return left(relativeViews: relativeViews, aligned: nil, context: context)
}
-
- @discardableResult
+
func left(of relativeView: PView, aligned: VerticalAlign) -> PinLayout {
func context() -> String { return "left(of: \(relativeView), aligned: \(aligned))" }
return left(relativeViews: [relativeView], aligned: aligned, context: context)
}
-
- @discardableResult
+
func left(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout {
func context() -> String { return "left(of: \(relativeViews), aligned: \(aligned))" }
return left(relativeViews: relativeViews, aligned: aligned, context: context)
@@ -109,31 +97,26 @@ extension PinLayoutImpl {
//
// right(of ...)
//
- @discardableResult
func right(of relativeView: PView) -> PinLayout {
func context() -> String { return "right(of: \(relativeView))" }
return right(relativeViews: [relativeView], aligned: nil, context: context)
}
-
- @discardableResult
+
func right(of relativeViews: [PView]) -> PinLayout {
func context() -> String { return "right(of: \(relativeViews))" }
return right(relativeViews: relativeViews, aligned: nil, context: context)
}
- @discardableResult
func right(of relativeView: PView, aligned: VerticalAlign) -> PinLayout {
func context() -> String { return "right(of: \(relativeView), aligned: \(aligned))" }
return right(relativeViews: [relativeView], aligned: aligned, context: context)
}
-
- @discardableResult
+
func right(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout {
func context() -> String { return "right(of: \(relativeViews), aligned: \(aligned))" }
return right(relativeViews: relativeViews, aligned: aligned, context: context)
}
-
- @discardableResult
+
func before(of relativeView: PView) -> PinLayout {
func context() -> String { return "before(of: \(relativeView))" }
if isLTR() {
@@ -142,8 +125,7 @@ extension PinLayoutImpl {
return right(relativeViews: [relativeView], aligned: nil, context: context)
}
}
-
- @discardableResult
+
func before(of relativeViews: [PView]) -> PinLayout {
func context() -> String { return "before(of: \(relativeViews))" }
if isLTR() {
@@ -152,8 +134,7 @@ extension PinLayoutImpl {
return right(relativeViews: relativeViews, aligned: nil, context: context)
}
}
-
- @discardableResult
+
func before(of relativeView: PView, aligned: VerticalAlign) -> PinLayout {
func context() -> String { return "before(of: \(relativeView), aligned: \(aligned))" }
if isLTR() {
@@ -162,8 +143,7 @@ extension PinLayoutImpl {
return right(relativeViews: [relativeView], aligned: aligned, context: context)
}
}
-
- @discardableResult
+
func before(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout {
func context() -> String { return "before(of: \(relativeViews), aligned: \(aligned))" }
if isLTR() {
@@ -172,8 +152,7 @@ extension PinLayoutImpl {
return right(relativeViews: relativeViews, aligned: aligned, context: context)
}
}
-
- @discardableResult
+
func after(of relativeView: PView) -> PinLayout {
func context() -> String { return "after(of: \(relativeView))" }
if isLTR() {
@@ -182,8 +161,7 @@ extension PinLayoutImpl {
return left(relativeViews: [relativeView], aligned: nil, context: context)
}
}
-
- @discardableResult
+
func after(of relativeViews: [PView]) -> PinLayout {
func context() -> String { return "after(of: \(relativeViews))" }
if isLTR() {
@@ -192,8 +170,7 @@ extension PinLayoutImpl {
return left(relativeViews: relativeViews, aligned: nil, context: context)
}
}
-
- @discardableResult
+
func after(of relativeView: PView, aligned: VerticalAlign) -> PinLayout {
func context() -> String { return "after(of: \(relativeView))" }
if isLTR() {
@@ -202,8 +179,7 @@ extension PinLayoutImpl {
return left(relativeViews: [relativeView], aligned: aligned, context: context)
}
}
-
- @discardableResult
+
func after(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout {
func context() -> String { return "after(of: \(relativeViews), aligned: \(aligned))" }
if isLTR() {
@@ -216,7 +192,6 @@ extension PinLayoutImpl {
// MARK: fileprivate
extension PinLayoutImpl {
- @discardableResult
fileprivate func above(relativeViews: [PView], aligned: HorizontalAlign?, context: Context) -> PinLayout {
guard let relativeViews = validateRelativeViews(relativeViews, context: context) else { return self }
@@ -240,7 +215,6 @@ extension PinLayoutImpl {
return self
}
- @discardableResult
fileprivate func below(relativeViews: [PView], aligned: HorizontalAlign?, context: Context) -> PinLayout {
guard let relativeViews = validateRelativeViews(relativeViews, context: context) else { return self }
@@ -391,4 +365,3 @@ extension PinLayoutImpl {
return relativeViews
}
}
-
diff --git a/Sources/Impl/PinLayoutImpl+Warning.swift b/Sources/Impl/PinLayoutImpl+Warning.swift
index e7958bd1..5d30c396 100644
--- a/Sources/Impl/PinLayoutImpl+Warning.swift
+++ b/Sources/Impl/PinLayoutImpl+Warning.swift
@@ -157,4 +157,3 @@ extension PinLayoutImpl {
return "UIEdgeInsets(top: \(insets.top), left: \(insets.left), bottom: \(insets.bottom), right: \(insets.right))"
}
}
-
diff --git a/Sources/Impl/PinLayoutImpl.swift b/Sources/Impl/PinLayoutImpl.swift
index 5b16dca1..ae01e5e9 100644
--- a/Sources/Impl/PinLayoutImpl.swift
+++ b/Sources/Impl/PinLayoutImpl.swift
@@ -101,17 +101,15 @@ class PinLayoutImpl: PinLayout {
//
// top, left, bottom, right
//
- @discardableResult func top() -> PinLayout {
+ func top() -> PinLayout {
top({ return "top()" })
return self
}
- @discardableResult
func top(_ value: CGFloat) -> PinLayout {
return top(value, { return "top(\(value))" })
}
-
- @discardableResult
+
func top(_ percent: Percent) -> PinLayout {
func context() -> String { return "top(\(percent.description))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
@@ -119,133 +117,112 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func top(_ insets: PEdgeInsets) -> PinLayout {
return top(insets.top, { return "top(\(insetsDescription(insets))" })
}
-
- @discardableResult
+
func left() -> PinLayout {
return left({ return "left()" })
}
- @discardableResult
func left(_ value: CGFloat) -> PinLayout {
return left(value, { return "left(\(value))" })
}
-
- @discardableResult
+
func left(_ percent: Percent) -> PinLayout {
return left(percent, { return "left(\(percent.description))" })
}
- @discardableResult
func left(_ insets: PEdgeInsets) -> PinLayout {
return left(insets.left, { return "left(\(insetsDescription(insets))" })
}
-
- @discardableResult
+
func start() -> PinLayout {
func context() -> String { return "start()" }
return isLTR() ? left(context) : right(context)
}
-
- @discardableResult
+
func start(_ value: CGFloat) -> PinLayout {
func context() -> String { return "start(\(value))" }
return isLTR() ? left(value, context) : right(value, context)
}
-
- @discardableResult
+
func start(_ percent: Percent) -> PinLayout {
func context() -> String { return "start(\(percent.description))" }
return isLTR() ? left(percent, context) : right(percent, context)
}
- @discardableResult
func start(_ insets: PEdgeInsets) -> PinLayout {
func context() -> String { return "start(\(insetsDescription(insets))" }
return isLTR() ? left(insets.left, context) : right(insets.right, context)
}
- @discardableResult func bottom() -> PinLayout {
+ func bottom() -> PinLayout {
return bottom({ return "bottom()" })
}
- @discardableResult
func bottom(_ value: CGFloat) -> PinLayout {
return bottom(value, { return "bottom(\(value))" })
}
-
- @discardableResult
+
func bottom(_ percent: Percent) -> PinLayout {
return bottom(percent, { return "bottom(\(percent.description))" })
}
- @discardableResult
func bottom(_ insets: PEdgeInsets) -> PinLayout {
return bottom(insets.bottom, { return "bottom(\(insetsDescription(insets))" })
}
- @discardableResult func right() -> PinLayout {
+ func right() -> PinLayout {
return right({ return "right()" })
}
- @discardableResult
func right(_ value: CGFloat) -> PinLayout {
return right(value, { return "right(\(value))" })
}
-
- @discardableResult
+
func right(_ percent: Percent) -> PinLayout {
return right(percent, { return "right(\(percent.description))" })
}
- @discardableResult
func right(_ insets: PEdgeInsets) -> PinLayout {
return right(insets.right, { return "right(\(insetsDescription(insets))" })
}
- @discardableResult func end() -> PinLayout {
+ func end() -> PinLayout {
func context() -> String { return "end()" }
return isLTR() ? right(context) : left(context)
}
-
- @discardableResult
+
func end(_ value: CGFloat) -> PinLayout {
func context() -> String { return "end(\(value))" }
return isLTR() ? right(value, context) : left(value, context)
}
-
- @discardableResult
+
func end(_ percent: Percent) -> PinLayout {
func context() -> String { return "end(\(percent.description))" }
return isLTR() ? right(percent, context) : left(percent, context)
}
- @discardableResult
func end(_ insets: PEdgeInsets) -> PinLayout {
func context() -> String { return "end(\(insetsDescription(insets))" }
return isLTR() ? right(insets.right, context) : left(insets.left, context)
}
- @discardableResult
func hCenter() -> PinLayout {
func context() -> String { return "hCenter()" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
setHorizontalCenter(layoutSuperviewRect.width / 2, context)
return self
}
-
- @discardableResult
+
func hCenter(_ value: CGFloat) -> PinLayout {
func context() -> String { return "hCenter(\(value))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
setHorizontalCenter((layoutSuperviewRect.width / 2) + value, context)
return self
}
-
- @discardableResult
+
func hCenter(_ percent: Percent) -> PinLayout {
func context() -> String { return "hCenter(\(percent.description))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
@@ -253,31 +230,27 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func vCenter() -> PinLayout {
func context() -> String { return "vCenter()" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
setVerticalCenter(layoutSuperviewRect.height / 2, context)
return self
}
-
- @discardableResult
+
func vCenter(_ value: CGFloat) -> PinLayout {
func context() -> String { return "vCenter(\(value))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
setVerticalCenter((layoutSuperviewRect.height / 2) + value, context)
return self
}
-
- @discardableResult
+
func vCenter(_ percent: Percent) -> PinLayout {
func context() -> String { return "vCenter(\(percent.description))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
setVerticalCenter((layoutSuperviewRect.height / 2) + percent.of(layoutSuperviewRect.height), context)
return self
}
-
- @discardableResult
+
func all() -> PinLayout {
top({ "all() top coordinate" })
bottom({ "all() bottom coordinate" })
@@ -286,7 +259,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func all(_ value: CGFloat) -> PinLayout {
top(value, { "all(\(value)) top coordinate" })
bottom(value, { "all(\(value)) bottom coordinate" })
@@ -302,57 +274,49 @@ class PinLayoutImpl: PinLayout {
right(insets.right, { "all(\(insets)) right coordinate" })
return self
}
-
- @discardableResult
+
func horizontally() -> PinLayout {
right({ "horizontally() right coordinate" })
left({ "horizontally() left coordinate" })
return self
}
- @discardableResult
func horizontally(_ value: CGFloat) -> PinLayout {
left(value, { return "horizontally(\(value)) left coordinate" })
right(value, { return "horizontally(\(value)) right coordinate" })
return self
}
- @discardableResult
func horizontally(_ percent: Percent) -> PinLayout {
left(percent, { return "horizontally(\(percent.description)) left coordinate" })
right(percent, { return "horizontally(\(percent.description)) right coordinate" })
return self
}
- @discardableResult
func horizontally(_ insets: PEdgeInsets) -> PinLayout {
left(insets.left, { return "horizontally(\(insets)) left coordinate" })
right(insets.right, { return "horizontally(\(insets)) right coordinate" })
return self
}
- @discardableResult
func vertically() -> PinLayout {
top({ "vertically() top coordinate" })
bottom({ "vertically() bottom coordinate" })
return self
}
- @discardableResult
func vertically(_ value: CGFloat) -> PinLayout {
top(value, { return "vertically(\(value)) top coordinate" })
bottom(value, { return "vertically(\(value)) bottom coordinate" })
return self
}
- @discardableResult
func vertically(_ percent: Percent) -> PinLayout {
top(percent, { return "vertically(\(percent.description)) top coordinate" })
bottom(percent, { return "vertically(\(percent.description)) bottom coordinate" })
return self
}
- @discardableResult
func vertically(_ insets: PEdgeInsets) -> PinLayout {
top(insets.top, { return "vertically(\(insets)) top coordinate" })
bottom(insets.bottom, { return "vertically(\(insets)) bottom coordinate" })
@@ -362,7 +326,6 @@ class PinLayoutImpl: PinLayout {
//
// top, left, bottom, right
//
- @discardableResult
func top(to edge: VerticalEdge) -> PinLayout {
func context() -> String { return relativeEdgeContext(method: "top", edge: edge) }
if let coordinate = computeCoordinate(forEdge: edge, context) {
@@ -370,8 +333,7 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func vCenter(to edge: VerticalEdge) -> PinLayout {
func context() -> String { return relativeEdgeContext(method: "vCenter", edge: edge) }
if let coordinate = computeCoordinate(forEdge: edge, context) {
@@ -380,7 +342,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func bottom(to edge: VerticalEdge) -> PinLayout {
func context() -> String { return relativeEdgeContext(method: "bottom", edge: edge) }
if let coordinate = computeCoordinate(forEdge: edge, context) {
@@ -388,8 +349,7 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func left(to edge: HorizontalEdge) -> PinLayout {
func context() -> String { return relativeEdgeContext(method: "left", edge: edge) }
if let coordinate = computeCoordinate(forEdge: edge, context) {
@@ -397,8 +357,7 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func hCenter(to edge: HorizontalEdge) -> PinLayout {
func context() -> String { return relativeEdgeContext(method: "hCenter", edge: edge) }
if let coordinate = computeCoordinate(forEdge: edge, context) {
@@ -406,8 +365,7 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func right(to edge: HorizontalEdge) -> PinLayout {
func context() -> String { return relativeEdgeContext(method: "right", edge: edge) }
if let coordinate = computeCoordinate(forEdge: edge, context) {
@@ -415,8 +373,7 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func start(to edge: HorizontalEdge) -> PinLayout {
func context() -> String { return relativeEdgeContext(method: "start", edge: edge) }
if let coordinate = computeCoordinate(forEdge: edge, context) {
@@ -424,8 +381,7 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func end(to edge: HorizontalEdge) -> PinLayout {
func context() -> String { return relativeEdgeContext(method: "end", edge: edge) }
if let coordinate = computeCoordinate(forEdge: edge, context) {
@@ -439,7 +395,6 @@ class PinLayoutImpl: PinLayout {
// centerLeft, center, centerRight,
// bottomLeft, bottomCenter, bottomRight,
//
- @discardableResult
func topLeft(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "topLeft", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -448,7 +403,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func topLeft() -> PinLayout {
return topLeft({ return "topLeft()" })
}
@@ -457,8 +411,7 @@ class PinLayoutImpl: PinLayout {
setTopLeft(CGPoint(x: 0, y: 0), { return "topLeft()" })
return self
}
-
- @discardableResult
+
func topStart(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "topStart", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -468,13 +421,11 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func topStart() -> PinLayout {
func context() -> String { return "topStart()" }
return isLTR() ? topLeft(context) : topRight(context)
}
-
- @discardableResult
+
func topCenter(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "topCenter", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -483,7 +434,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func topCenter() -> PinLayout {
func context() -> String { return "topCenter()" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
@@ -491,7 +441,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func topRight(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "topRight", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -500,7 +449,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func topRight() -> PinLayout {
return topRight({ return "topRight()" })
}
@@ -510,8 +458,7 @@ class PinLayoutImpl: PinLayout {
setTopRight(CGPoint(x: layoutSuperviewRect.width, y: 0), context)
return self
}
-
- @discardableResult
+
func topEnd(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "topEnd", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -520,14 +467,12 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func topEnd() -> PinLayout {
func context() -> String { return "topEnd()" }
return isLTR() ? topRight(context) : topLeft(context)
}
-
- @discardableResult
+
func centerLeft(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "centerLeft", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -535,8 +480,7 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func centerLeft() -> PinLayout {
return centerLeft({ return "centerLeft()" })
}
@@ -547,7 +491,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func centerStart(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "centerStart", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -556,14 +499,12 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func centerStart() -> PinLayout {
func context() -> String { return "centerStart()" }
return isLTR() ? centerLeft(context) : centerRight(context)
}
-
- @discardableResult
+
func center(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "center", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -571,16 +512,14 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func center() -> PinLayout {
func context() -> String { return "center()" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
setCenter(CGPoint(x: layoutSuperviewRect.width / 2, y: layoutSuperviewRect.height / 2), context)
return self
}
-
- @discardableResult
+
func centerRight(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "centerRight", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -588,20 +527,17 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func centerRight() -> PinLayout {
return centerRight({ return "centerRight()" })
}
-
- @discardableResult
+
fileprivate func centerRight(_ context: Context) -> PinLayout {
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
setCenterRight(CGPoint(x: layoutSuperviewRect.width, y: layoutSuperviewRect.height / 2), context)
return self
}
-
- @discardableResult
+
func centerEnd(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "centerEnd", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -610,14 +546,12 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func centerEnd() -> PinLayout {
func context() -> String { return "centerEnd()" }
return isLTR() ? centerRight(context) : centerLeft(context)
}
-
- @discardableResult
+
func bottomLeft(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "bottomLeft", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -626,19 +560,16 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func bottomLeft() -> PinLayout {
return bottomLeft({ return "bottomLeft()" })
}
-
- @discardableResult
+
fileprivate func bottomLeft(_ context: Context) -> PinLayout {
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
setBottomLeft(CGPoint(x: 0, y: layoutSuperviewRect.height), context)
return self
}
-
- @discardableResult
+
func bottomStart(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "bottomStart", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -647,14 +578,12 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func bottomStart() -> PinLayout {
func context() -> String { return "bottomStart()" }
return isLTR() ? bottomLeft(context) : bottomRight(context)
}
- @discardableResult
func bottomCenter(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "bottomCenter", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -663,7 +592,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func bottomCenter() -> PinLayout {
func context() -> String { return "bottomCenter()" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
@@ -671,7 +599,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func bottomRight(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "bottomRight", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -680,19 +607,16 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func bottomRight() -> PinLayout {
return bottomRight({ return "bottomRight()" })
}
-
- @discardableResult
+
fileprivate func bottomRight(_ context: Context) -> PinLayout {
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
setBottomRight(CGPoint(x: layoutSuperviewRect.width, y: layoutSuperviewRect.height), context)
return self
}
- @discardableResult
func bottomEnd(to anchor: Anchor) -> PinLayout {
func context() -> String { return relativeAnchorContext(method: "bottomEnd", anchor: anchor) }
if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) {
@@ -701,8 +625,7 @@ class PinLayoutImpl: PinLayout {
}
return self
}
-
- @discardableResult
+
func bottomEnd() -> PinLayout {
func context() -> String { return "bottomEnd()" }
return isLTR() ? bottomRight(context) : bottomLeft(context)
@@ -711,86 +634,72 @@ class PinLayoutImpl: PinLayout {
//
// width, height
//
- @discardableResult
func width(_ width: CGFloat) -> PinLayout {
return setWidth(width, { return "width(\(width))" })
}
-
- @discardableResult
+
func width(_ percent: Percent) -> PinLayout {
func context() -> String { return "width(\(percent.description))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
return setWidth(percent.of(layoutSuperviewRect.width), context)
}
- @discardableResult
func width(of view: PView) -> PinLayout {
return setWidth(view.bounds.width, { return "width(of: \(viewDescription(view)))" })
}
-
- @discardableResult
+
func minWidth(_ width: CGFloat) -> PinLayout {
setMinWidth(width, { return "minWidth(\(width))" })
return self
}
-
- @discardableResult
+
func minWidth(_ percent: Percent) -> PinLayout {
func context() -> String { return "minWidth(\(percent.description))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
return setMinWidth(percent.of(layoutSuperviewRect.width), context)
}
-
- @discardableResult
+
func maxWidth(_ width: CGFloat) -> PinLayout {
setMaxWidth(width, { return "maxWidth(\(width))" })
return self
}
-
- @discardableResult
+
func maxWidth(_ percent: Percent) -> PinLayout {
func context() -> String { return "maxWidth(\(percent.description))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
return setMaxWidth(percent.of(layoutSuperviewRect.width), context)
}
- @discardableResult
func height(_ height: CGFloat) -> PinLayout {
return setHeight(height, { return "height(\(height))" })
}
-
- @discardableResult
+
func height(_ percent: Percent) -> PinLayout {
func context() -> String { return "height(\(percent.description))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
return setHeight(percent.of(layoutSuperviewRect.height), context)
}
- @discardableResult
func height(of view: PView) -> PinLayout {
return setHeight(view.bounds.height, { return "height(of: \(viewDescription(view)))" })
}
-
- @discardableResult
+
func minHeight(_ height: CGFloat) -> PinLayout {
setMinHeight(height, { return "minHeight(\(height))" })
return self
}
-
- @discardableResult
+
func minHeight(_ percent: Percent) -> PinLayout {
func context() -> String { return "minHeight(\(percent.description))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
return setMinHeight(percent.of(layoutSuperviewRect.height), context)
}
-
- @discardableResult
+
func maxHeight(_ height: CGFloat) -> PinLayout {
setMaxHeight(height, { return "maxHeight(\(height))" })
return self
}
-
- @discardableResult
+
func maxHeight(_ percent: Percent) -> PinLayout {
func context() -> String { return "maxHeight(\(percent.description))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
@@ -800,50 +709,42 @@ class PinLayoutImpl: PinLayout {
//
// size, sizeToFit
//
- @discardableResult
func size(_ size: CGSize) -> PinLayout {
return setSize(size, { return "size(CGSize(width: \(size.width), height: \(size.height)))" })
}
-
- @discardableResult
+
func size(_ sideLength: CGFloat) -> PinLayout {
return setSize(CGSize(width: sideLength, height: sideLength), { return "size(sideLength: \(sideLength))" })
}
-
- @discardableResult
+
func size(_ percent: Percent) -> PinLayout {
func context() -> String { return "size(\(percent.description))" }
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
let size = CGSize(width: percent.of(layoutSuperviewRect.width), height: percent.of(layoutSuperviewRect.height))
return setSize(size, context)
}
-
- @discardableResult
+
func size(of view: PView) -> PinLayout {
func context() -> String { return "size(of \(viewDescription(view)))" }
return setSize(view.bounds.size, context)
}
-
-// @discardableResult
+
// func wrapSubViews() -> PinLayout {
// let neededWidth = view.subviews.max(by: { subview1, subview2 in subview1.frame.maxX < subview2.frame.maxX })?.frame.maxX ?? 0
// let neededHeight = view.subviews.max(by: { subview1, subview2 in subview1.frame.maxY < subview2.frame.maxY })?.frame.maxY ?? 0
//
// return setSize(CGSize(width: neededWidth, height: neededHeight), { return "wrapSubViews()" })
// }
-
- @discardableResult
+
func aspectRatio(_ ratio: CGFloat) -> PinLayout {
return setAspectRatio(ratio, context: { "aspectRatio(\(ratio))" })
}
-
- @discardableResult
+
func aspectRatio(of view: PView) -> PinLayout {
return setAspectRatio(view.bounds.width / view.bounds.height, context: { "aspectRatio(of: \(viewDescription(view)))" })
}
#if os(iOS) || os(tvOS)
- @discardableResult
func aspectRatio() -> PinLayout {
func context() -> String { return "aspectRatio()" }
if let imageView = view as? UIImageView {
@@ -858,26 +759,22 @@ class PinLayoutImpl: PinLayout {
return self
}
#endif
-
- @discardableResult
+
func sizeToFit(_ fitType: FitType) -> PinLayout {
return setFitSize(fitType: fitType, { return "sizeToFit(\(fitType.name))" })
}
#if os(iOS) || os(tvOS)
- @discardableResult
func fitSize() -> PinLayout {
return setFitSize(fitType: nil, { return "fitSize()" })
}
#endif
- @discardableResult
func justify(_ value: HorizontalAlign) -> PinLayout {
justify = value
return self
}
-
- @discardableResult
+
func align(_ value: VerticalAlign) -> PinLayout {
align = value
return self
@@ -886,88 +783,75 @@ class PinLayoutImpl: PinLayout {
//
// Margins
//
- @discardableResult
func marginTop(_ value: CGFloat) -> PinLayout {
marginTop = value
return self
}
- @discardableResult
func marginTop(_ percent: Percent) -> PinLayout {
func context() -> String { return "marginTop(\(percent.description))" }
return marginTop(percent, context)
}
- @discardableResult
private func marginTop(_ percent: Percent, _ context: Context) -> Self {
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
marginTop = percent.of(layoutSuperviewRect.height)
return self
}
- @discardableResult
func marginLeft(_ value: CGFloat) -> PinLayout {
marginLeft = value
return self
}
- @discardableResult
func marginLeft(_ percent: Percent) -> PinLayout {
func context() -> String { return "marginLeft(\(percent.description))" }
return marginLeft(percent, context)
}
- @discardableResult
private func marginLeft(_ percent: Percent, _ context: Context) -> Self {
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
marginLeft = percent.of(layoutSuperviewRect.width)
return self
}
- @discardableResult
func marginBottom(_ value: CGFloat) -> PinLayout {
marginBottom = value
return self
}
- @discardableResult
func marginBottom(_ percent: Percent) -> PinLayout {
func context() -> String { return "marginBottom(\(percent.description))" }
return marginBottom(percent, context)
}
- @discardableResult
private func marginBottom(_ percent: Percent, _ context: Context) -> Self {
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
marginBottom = percent.of(layoutSuperviewRect.height)
return self
}
- @discardableResult
func marginRight(_ value: CGFloat) -> PinLayout {
marginRight = value
return self
}
- @discardableResult
func marginRight(_ percent: Percent) -> PinLayout {
func context() -> String { return "marginRight(\(percent.description))" }
return marginRight(percent, context)
}
- @discardableResult
private func marginRight(_ percent: Percent, _ context: Context) -> Self {
guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self }
marginRight = percent.of(layoutSuperviewRect.width)
return self
}
-
+
@discardableResult
func marginStart(_ value: CGFloat) -> PinLayout {
return isLTR() ? marginLeft(value) : marginRight(value)
}
- @discardableResult
func marginStart(_ percent: Percent) -> PinLayout {
func context() -> String { return "marginStart(\(percent.description))" }
return isLTR() ? marginLeft(percent, context) : marginRight(percent, context)
@@ -978,49 +862,41 @@ class PinLayoutImpl: PinLayout {
return isLTR() ? marginRight(value) : marginLeft(value)
}
- @discardableResult
func marginEnd(_ percent: Percent) -> PinLayout {
func context() -> String { return "marginEnd(\(percent.description))" }
return isLTR() ? marginRight(percent, context) : marginLeft(percent, context)
}
- @discardableResult
func marginHorizontal(_ value: CGFloat) -> PinLayout {
marginLeft = value
marginRight = value
return self
}
- @discardableResult
func marginHorizontal(_ percent: Percent) -> PinLayout {
func context() -> String { return "marginHorizontal(\(percent.description))" }
return marginHorizontal(percent, context)
}
- @discardableResult
private func marginHorizontal(_ percent: Percent, _ context: Context) -> Self {
return marginLeft(percent, context).marginRight(percent, context)
}
- @discardableResult
func marginVertical(_ value: CGFloat) -> PinLayout {
marginTop = value
marginBottom = value
return self
}
- @discardableResult
func marginVertical(_ percent: Percent) -> PinLayout {
func context() -> String { return "marginVertical(\(percent.description))" }
return marginVertical(percent, context)
}
- @discardableResult
private func marginVertical(_ percent: Percent, _ context: Context) -> Self {
return marginTop(percent, context).marginBottom(percent, context)
}
- @discardableResult
func margin(_ insets: PEdgeInsets) -> PinLayout {
marginTop = insets.top
marginBottom = insets.bottom
@@ -1031,7 +907,6 @@ class PinLayoutImpl: PinLayout {
#if os(iOS) || os(tvOS)
@available(tvOS 11.0, iOS 11.0, *)
- @discardableResult
func margin(_ directionalInsets: NSDirectionalEdgeInsets) -> PinLayout {
marginTop = directionalInsets.top
marginBottom = directionalInsets.bottom
@@ -1041,7 +916,6 @@ class PinLayoutImpl: PinLayout {
}
#endif
- @discardableResult
func margin(_ value: CGFloat) -> PinLayout {
marginTop = value
marginLeft = value
@@ -1050,7 +924,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func margin(_ percent: Percent) -> PinLayout {
func context() -> String { return "margin(\(percent.description))" }
return marginTop(percent, context)
@@ -1059,7 +932,6 @@ class PinLayoutImpl: PinLayout {
.marginRight(percent, context)
}
- @discardableResult
func margin(_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) -> PinLayout {
marginTop = top
marginLeft = left
@@ -1068,7 +940,6 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func margin(_ top: Percent, _ left: Percent, _ bottom: Percent, _ right: Percent) -> PinLayout {
func context() -> String {
return "margin(top: \(top.description), left: \(left.description), bottom: \(bottom.description), right: \(right.description)"
@@ -1079,7 +950,7 @@ class PinLayoutImpl: PinLayout {
.marginRight(right, context)
}
- @discardableResult func margin(_ vertical: CGFloat, _ horizontal: CGFloat) -> PinLayout {
+ func margin(_ vertical: CGFloat, _ horizontal: CGFloat) -> PinLayout {
marginTop = vertical
marginLeft = horizontal
marginBottom = vertical
@@ -1087,13 +958,12 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func margin(_ vertical: Percent, _ horizontal: Percent) -> PinLayout {
func context() -> String { return "margin(vertical: \(vertical.description), horizontal: \(horizontal.description)"}
return marginVertical(vertical, context).marginHorizontal(horizontal, context)
}
- @discardableResult func margin(_ top: CGFloat, _ horizontal: CGFloat, _ bottom: CGFloat) -> PinLayout {
+ func margin(_ top: CGFloat, _ horizontal: CGFloat, _ bottom: CGFloat) -> PinLayout {
marginTop = top
marginLeft = horizontal
marginBottom = bottom
@@ -1101,13 +971,11 @@ class PinLayoutImpl: PinLayout {
return self
}
- @discardableResult
func margin(_ top: Percent, _ horizontal: Percent, _ bottom: Percent) -> PinLayout {
func context() -> String { return "margin(top: \(top.description), horizontal: \(horizontal.description), bottom: \(bottom.description)"}
return marginTop(top, context).marginHorizontal(horizontal, context).marginBottom(bottom, context)
}
- @discardableResult
func pinEdges() -> PinLayout {
shouldPinEdges = true
return self
@@ -1134,7 +1002,7 @@ extension PinLayoutImpl {
}
return self
}
-
+
@discardableResult
internal func setAspectRatio(_ ratio: CGFloat, context: Context) -> PinLayout {
if let fitType = fitType {
diff --git a/Sources/Impl/PinSafeArea.swift b/Sources/Impl/PinSafeArea.swift
index ba57f4c1..1938dd73 100644
--- a/Sources/Impl/PinSafeArea.swift
+++ b/Sources/Impl/PinSafeArea.swift
@@ -261,4 +261,3 @@ extension UIView {
}
}
#endif
-
diff --git a/Sources/Impl/TypesImpl.swift b/Sources/Impl/TypesImpl.swift
index 4418fadd..eb1060d2 100644
--- a/Sources/Impl/TypesImpl.swift
+++ b/Sources/Impl/TypesImpl.swift
@@ -209,4 +209,3 @@ internal extension FitType {
return self == .widthFlexible || self == .heightFlexible
}
}
-
diff --git a/Sources/NSView+PinLayout.swift b/Sources/NSView+PinLayout.swift
index 6e564a13..7536316f 100644
--- a/Sources/NSView+PinLayout.swift
+++ b/Sources/NSView+PinLayout.swift
@@ -27,5 +27,11 @@ public extension NSView {
public var edge: EdgeList {
return EdgeListImpl(view: self)
}
+
+ // Expose PinLayout's objective-c interface.
+ @objc public var pinObjc: PinLayoutObjC {
+ return PinLayoutObjCImpl(view: self, keepTransform: true)
+ }
}
+
#endif
diff --git a/Sources/ObjectiveC/PinLayoutObjC.swift b/Sources/ObjectiveC/PinLayoutObjC.swift
index f7d9ade7..0eb16a64 100644
--- a/Sources/ObjectiveC/PinLayoutObjC.swift
+++ b/Sources/ObjectiveC/PinLayoutObjC.swift
@@ -21,14 +21,9 @@ import Foundation
#if os(iOS) || os(tvOS)
import UIKit
-
-// MARK: - PinLayout UIView's extension
-public extension UIView {
- // Expose PinLayout's objective-c interface.
- @objc public var pinObjc: PinLayoutObjC {
- return PinLayoutObjCImpl(view: self, keepTransform: true)
- }
-}
+#else
+import AppKit
+#endif
/**
We must have a different interface for objective-c. The PinLayout's Swift interface use some
@@ -138,35 +133,67 @@ public extension UIView {
//
// MARK: Layout using relative positioning
//
- @discardableResult func above(of: UIView) -> PinLayoutObjC
- @discardableResult func above(ofViews: [UIView]) -> PinLayoutObjC
- @discardableResult func above(of: UIView, aligned: HorizontalAlign) -> PinLayoutObjC
- @discardableResult func above(ofViews: [UIView], aligned: HorizontalAlign) -> PinLayoutObjC
-
- @discardableResult func below(of: UIView) -> PinLayoutObjC
- @discardableResult func below(ofViews: [UIView]) -> PinLayoutObjC
- @discardableResult func below(of: UIView, aligned: HorizontalAlign) -> PinLayoutObjC
- @discardableResult func below(ofViews: [UIView], aligned: HorizontalAlign) -> PinLayoutObjC
-
- @discardableResult func left(of: UIView) -> PinLayoutObjC
- @discardableResult func left(ofViews: [UIView]) -> PinLayoutObjC
- @discardableResult func left(of: UIView, aligned: VerticalAlign) -> PinLayoutObjC
- @discardableResult func left(ofViews: [UIView], aligned: VerticalAlign) -> PinLayoutObjC
-
- @discardableResult func right(of: UIView) -> PinLayoutObjC
- @discardableResult func right(ofViews: [UIView]) -> PinLayoutObjC
- @discardableResult func right(of: UIView, aligned: VerticalAlign) -> PinLayoutObjC
- @discardableResult func right(ofViews: [UIView], aligned: VerticalAlign) -> PinLayoutObjC
-
- // RTL support
- @discardableResult func before(of: UIView) -> PinLayoutObjC
- @discardableResult func before(ofViews: [UIView]) -> PinLayoutObjC
- @discardableResult func before(of: UIView, aligned: VerticalAlign) -> PinLayoutObjC
- @discardableResult func before(ofViews: [UIView], aligned: VerticalAlign) -> PinLayoutObjC
- @discardableResult func after(of: UIView) -> PinLayoutObjC
- @discardableResult func after(ofViews: [UIView]) -> PinLayoutObjC
- @discardableResult func after(of: UIView, aligned: VerticalAlign) -> PinLayoutObjC
- @discardableResult func after(ofViews: [UIView], aligned: VerticalAlign) -> PinLayoutObjC
+ #if os(iOS) || os(tvOS)
+ @discardableResult func above(of: UIView) -> PinLayoutObjC
+ @discardableResult func above(ofViews: [UIView]) -> PinLayoutObjC
+ @discardableResult func above(of: UIView, aligned: HorizontalAlign) -> PinLayoutObjC
+ @discardableResult func above(ofViews: [UIView], aligned: HorizontalAlign) -> PinLayoutObjC
+
+ @discardableResult func below(of: UIView) -> PinLayoutObjC
+ @discardableResult func below(ofViews: [UIView]) -> PinLayoutObjC
+ @discardableResult func below(of: UIView, aligned: HorizontalAlign) -> PinLayoutObjC
+ @discardableResult func below(ofViews: [UIView], aligned: HorizontalAlign) -> PinLayoutObjC
+
+ @discardableResult func left(of: UIView) -> PinLayoutObjC
+ @discardableResult func left(ofViews: [UIView]) -> PinLayoutObjC
+ @discardableResult func left(of: UIView, aligned: VerticalAlign) -> PinLayoutObjC
+ @discardableResult func left(ofViews: [UIView], aligned: VerticalAlign) -> PinLayoutObjC
+
+ @discardableResult func right(of: UIView) -> PinLayoutObjC
+ @discardableResult func right(ofViews: [UIView]) -> PinLayoutObjC
+ @discardableResult func right(of: UIView, aligned: VerticalAlign) -> PinLayoutObjC
+ @discardableResult func right(ofViews: [UIView], aligned: VerticalAlign) -> PinLayoutObjC
+
+ // RTL support
+ @discardableResult func before(of: UIView) -> PinLayoutObjC
+ @discardableResult func before(ofViews: [UIView]) -> PinLayoutObjC
+ @discardableResult func before(of: UIView, aligned: VerticalAlign) -> PinLayoutObjC
+ @discardableResult func before(ofViews: [UIView], aligned: VerticalAlign) -> PinLayoutObjC
+ @discardableResult func after(of: UIView) -> PinLayoutObjC
+ @discardableResult func after(ofViews: [UIView]) -> PinLayoutObjC
+ @discardableResult func after(of: UIView, aligned: VerticalAlign) -> PinLayoutObjC
+ @discardableResult func after(ofViews: [UIView], aligned: VerticalAlign) -> PinLayoutObjC
+ #elseif os(macOS)
+ @discardableResult func above(of: NSView) -> PinLayoutObjC
+ @discardableResult func above(ofViews: [NSView]) -> PinLayoutObjC
+ @discardableResult func above(of: NSView, aligned: HorizontalAlign) -> PinLayoutObjC
+ @discardableResult func above(ofViews: [NSView], aligned: HorizontalAlign) -> PinLayoutObjC
+
+ @discardableResult func below(of: NSView) -> PinLayoutObjC
+ @discardableResult func below(ofViews: [NSView]) -> PinLayoutObjC
+ @discardableResult func below(of: NSView, aligned: HorizontalAlign) -> PinLayoutObjC
+ @discardableResult func below(ofViews: [NSView], aligned: HorizontalAlign) -> PinLayoutObjC
+
+ @discardableResult func left(of: NSView) -> PinLayoutObjC
+ @discardableResult func left(ofViews: [NSView]) -> PinLayoutObjC
+ @discardableResult func left(of: NSView, aligned: VerticalAlign) -> PinLayoutObjC
+ @discardableResult func left(ofViews: [NSView], aligned: VerticalAlign) -> PinLayoutObjC
+
+ @discardableResult func right(of: NSView) -> PinLayoutObjC
+ @discardableResult func right(ofViews: [NSView]) -> PinLayoutObjC
+ @discardableResult func right(of: NSView, aligned: VerticalAlign) -> PinLayoutObjC
+ @discardableResult func right(ofViews: [NSView], aligned: VerticalAlign) -> PinLayoutObjC
+
+ // RTL support
+ @discardableResult func before(of: NSView) -> PinLayoutObjC
+ @discardableResult func before(ofViews: [NSView]) -> PinLayoutObjC
+ @discardableResult func before(of: NSView, aligned: VerticalAlign) -> PinLayoutObjC
+ @discardableResult func before(ofViews: [NSView], aligned: VerticalAlign) -> PinLayoutObjC
+ @discardableResult func after(of: NSView) -> PinLayoutObjC
+ @discardableResult func after(ofViews: [NSView]) -> PinLayoutObjC
+ @discardableResult func after(of: NSView, aligned: VerticalAlign) -> PinLayoutObjC
+ @discardableResult func after(ofViews: [NSView], aligned: VerticalAlign) -> PinLayoutObjC
+ #endif
//
// MARK: justify / align
@@ -179,7 +206,12 @@ public extension UIView {
//
@discardableResult func width(_ width: CGFloat) -> PinLayoutObjC
@discardableResult func width(percent: CGFloat) -> PinLayoutObjC
+ #if os(iOS) || os(tvOS)
@discardableResult func width(of view: UIView) -> PinLayoutObjC
+ #elseif os(macOS)
+ @discardableResult func width(of view: NSView) -> PinLayoutObjC
+ #endif
+
@discardableResult func minWidth(_ width: CGFloat) -> PinLayoutObjC
@discardableResult func minWidth(percent: CGFloat) -> PinLayoutObjC
@discardableResult func maxWidth(_ width: CGFloat) -> PinLayoutObjC
@@ -187,7 +219,12 @@ public extension UIView {
@discardableResult func height(_ height: CGFloat) -> PinLayoutObjC
@discardableResult func height(percent: CGFloat) -> PinLayoutObjC
+ #if os(iOS) || os(tvOS)
@discardableResult func height(of view: UIView) -> PinLayoutObjC
+ #elseif os(macOS)
+ @discardableResult func height(of view: NSView) -> PinLayoutObjC
+ #endif
+
@discardableResult func minHeight(_ height: CGFloat) -> PinLayoutObjC
@discardableResult func minHeight(percent: CGFloat) -> PinLayoutObjC
@discardableResult func maxHeight(_ height: CGFloat) -> PinLayoutObjC
@@ -196,7 +233,11 @@ public extension UIView {
@discardableResult func size(_ size: CGSize) -> PinLayoutObjC
@discardableResult func size(length: CGFloat) -> PinLayoutObjC
@discardableResult func size(percent: CGFloat) -> PinLayoutObjC
+ #if os(iOS) || os(tvOS)
@discardableResult func size(of view: UIView) -> PinLayoutObjC
+ #elseif os(macOS)
+ @discardableResult func size(of view: NSView) -> PinLayoutObjC
+ #endif
/**
Set the view aspect ratio.
@@ -220,17 +261,24 @@ public extension UIView {
* AspectRatio respects the min (minWidth/minHeight) and the max (maxWidth/maxHeight)
dimensions of an item.
*/
+ #if os(iOS) || os(tvOS)
@discardableResult func aspectRatio(of view: UIView) -> PinLayoutObjC
+ #elseif os(macOS)
+ @discardableResult func aspectRatio(of view: NSView) -> PinLayoutObjC
+ #endif
+
+
/**
If the layouted view is an UIImageView, this method will set the aspectRatio using
the UIImageView's image dimension.
For other types of views, this method as no impact.
*/
+ #if os(iOS) || os(tvOS)
@discardableResult func aspectRatio() -> PinLayoutObjC
+ #endif
@discardableResult func sizeToFit(_ fitType: Fit) -> PinLayoutObjC
- @discardableResult func fitSize() -> PinLayoutObjC
//
// MARK: Margins
@@ -289,7 +337,11 @@ public extension UIView {
Set all margins using UIEdgeInsets.
This method is particularly useful to set all margins using iOS 11 `UIView.safeAreaInsets`.
*/
+ #if os(iOS) || os(tvOS)
@discardableResult func margin(insets: UIEdgeInsets) -> PinLayoutObjC
+ #elseif os(macOS)
+ @discardableResult func margin(insets: NSEdgeInsets) -> PinLayoutObjC
+ #endif
/**
Set margins using NSDirectionalEdgeInsets.
@@ -335,5 +387,3 @@ public extension UIView {
case widthFlexible
case heightFlexible
}
-
-#endif
diff --git a/Sources/ObjectiveC/PinLayoutObjCImpl.swift b/Sources/ObjectiveC/PinLayoutObjCImpl.swift
index 89f7cc78..87ad03a7 100644
--- a/Sources/ObjectiveC/PinLayoutObjCImpl.swift
+++ b/Sources/ObjectiveC/PinLayoutObjCImpl.swift
@@ -19,11 +19,14 @@
#if os(iOS) || os(tvOS)
import UIKit
+#else
+import AppKit
+#endif
-@objc public class PinLayoutObjCImpl: NSObject, PinLayoutObjC {
+@objc class PinLayoutObjCImpl: NSObject, PinLayoutObjC {
fileprivate var impl: PinLayoutImpl?
- init(view: UIView, keepTransform: Bool) {
+ init(view: PView, keepTransform: Bool) {
impl = PinLayoutImpl(view: view, keepTransform: keepTransform)
}
@@ -33,589 +36,586 @@ import UIKit
}
}
- public func layout() {
+ func layout() {
// With objective-c PinLayoutObjCImpl instance are sometimes deallocated only after the context has been quit. For this reason
// developpers must call the layout: method implicetely.
impl?.layout()
impl = nil
}
-
- public func top() -> PinLayoutObjC {
- impl?.top()
+
+ func top() -> PinLayoutObjC {
+ _ = impl?.top()
return self
}
- public func top(_ value: CGFloat) -> PinLayoutObjC {
- impl?.top(value)
+ func top(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.top(value)
return self
}
- public func top(percent: CGFloat) -> PinLayoutObjC {
- impl?.top(percent%)
+ func top(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.top(percent%)
return self
}
- public func left() -> PinLayoutObjC {
- impl?.left()
+ func left() -> PinLayoutObjC {
+ _ = impl?.left()
return self
}
- public func left(_ value: CGFloat) -> PinLayoutObjC {
- impl?.left(value)
+ func left(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.left(value)
return self
}
- public func left(percent: CGFloat) -> PinLayoutObjC {
- impl?.left(percent%)
+ func left(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.left(percent%)
return self
}
- public func bottom() -> PinLayoutObjC {
- impl?.bottom()
+ func bottom() -> PinLayoutObjC {
+ _ = impl?.bottom()
return self
}
- public func bottom(_ value: CGFloat) -> PinLayoutObjC {
- impl?.bottom(value)
+ func bottom(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.bottom(value)
return self
}
- public func bottom(percent: CGFloat) -> PinLayoutObjC {
- impl?.bottom(percent%)
+ func bottom(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.bottom(percent%)
return self
}
- public func right() -> PinLayoutObjC {
- impl?.right()
+ func right() -> PinLayoutObjC {
+ _ = impl?.right()
return self
}
- public func right(_ value: CGFloat) -> PinLayoutObjC {
- impl?.right(value)
+ func right(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.right(value)
return self
}
- public func right(percent: CGFloat) -> PinLayoutObjC {
- impl?.right(percent%)
+ func right(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.right(percent%)
return self
}
- public func hCenter() -> PinLayoutObjC {
- impl?.hCenter()
+ func hCenter() -> PinLayoutObjC {
+ _ = impl?.hCenter()
return self
}
- public func hCenter(_ value: CGFloat) -> PinLayoutObjC {
- impl?.hCenter(value)
+ func hCenter(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.hCenter(value)
return self
}
- public func hCenter(percent: CGFloat) -> PinLayoutObjC {
- impl?.hCenter(percent%)
+ func hCenter(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.hCenter(percent%)
return self
}
- public func vCenter() -> PinLayoutObjC {
- impl?.vCenter()
+ func vCenter() -> PinLayoutObjC {
+ _ = impl?.vCenter()
return self
}
- public func vCenter(_ value: CGFloat) -> PinLayoutObjC {
- impl?.vCenter(value)
+ func vCenter(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.vCenter(value)
return self
}
- public func vCenter(percent: CGFloat) -> PinLayoutObjC {
- impl?.vCenter(percent%)
+ func vCenter(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.vCenter(percent%)
return self
}
- public func start() -> PinLayoutObjC {
- impl?.start()
+ func start() -> PinLayoutObjC {
+ _ = impl?.start()
return self
}
- public func start(_ value: CGFloat) -> PinLayoutObjC {
- impl?.start(value)
+ func start(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.start(value)
return self
}
- public func start(percent: CGFloat) -> PinLayoutObjC {
- impl?.start(percent%)
+ func start(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.start(percent%)
return self
}
- public func end() -> PinLayoutObjC {
- impl?.end()
+ func end() -> PinLayoutObjC {
+ _ = impl?.end()
return self
}
- public func end(_ value: CGFloat) -> PinLayoutObjC {
- impl?.end(value)
+ func end(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.end(value)
return self
}
- public func end(percent: CGFloat) -> PinLayoutObjC {
- impl?.end(percent%)
+ func end(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.end(percent%)
return self
}
- public func top(to edge: VerticalEdge) -> PinLayoutObjC {
- impl?.top(to: edge)
+ func top(to edge: VerticalEdge) -> PinLayoutObjC {
+ _ = impl?.top(to: edge)
return self
}
- public func vCenter(to edge: VerticalEdge) -> PinLayoutObjC {
- impl?.vCenter(to: edge)
+ func vCenter(to edge: VerticalEdge) -> PinLayoutObjC {
+ _ = impl?.vCenter(to: edge)
return self
}
- public func bottom(to edge: VerticalEdge) -> PinLayoutObjC {
- impl?.bottom(to: edge)
+ func bottom(to edge: VerticalEdge) -> PinLayoutObjC {
+ _ = impl?.bottom(to: edge)
return self
}
- public func left(to edge: HorizontalEdge) -> PinLayoutObjC {
- impl?.left(to: edge)
+ func left(to edge: HorizontalEdge) -> PinLayoutObjC {
+ _ = impl?.left(to: edge)
return self
}
- public func hCenter(to edge: HorizontalEdge) -> PinLayoutObjC {
- impl?.hCenter(to: edge)
+ func hCenter(to edge: HorizontalEdge) -> PinLayoutObjC {
+ _ = impl?.hCenter(to: edge)
return self
}
- public func right(to edge: HorizontalEdge) -> PinLayoutObjC {
- impl?.right(to: edge)
+ func right(to edge: HorizontalEdge) -> PinLayoutObjC {
+ _ = impl?.right(to: edge)
return self
}
- public func start(to edge: HorizontalEdge) -> PinLayoutObjC {
- impl?.start(to: edge)
+ func start(to edge: HorizontalEdge) -> PinLayoutObjC {
+ _ = impl?.start(to: edge)
return self
}
- public func end(to edge: HorizontalEdge) -> PinLayoutObjC {
- impl?.end(to: edge)
+ func end(to edge: HorizontalEdge) -> PinLayoutObjC {
+ _ = impl?.end(to: edge)
return self
}
- public func all() -> PinLayoutObjC {
- impl?.all()
+ func all() -> PinLayoutObjC {
+ _ = impl?.all()
return self
}
- public func horizontally() -> PinLayoutObjC {
- impl?.horizontally()
+ func horizontally() -> PinLayoutObjC {
+ _ = impl?.horizontally()
return self
}
- public func horizontally(_ value: CGFloat) -> PinLayoutObjC {
- impl?.horizontally(value)
+ func horizontally(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.horizontally(value)
return self
}
- public func vertically() -> PinLayoutObjC {
- impl?.vertically()
+ func vertically() -> PinLayoutObjC {
+ _ = impl?.vertically()
return self
}
- public func vertically(_ value: CGFloat) -> PinLayoutObjC {
- impl?.vertically(value)
- return self
- }
-
- public func topLeft(to anchor: Anchor) -> PinLayoutObjC {
- impl?.topLeft(to: anchor)
+ func vertically(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.vertically(value)
return self
}
- public func topLeft() -> PinLayoutObjC {
- impl?.topLeft()
+ func topLeft(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.topLeft(to: anchor)
return self
}
- public func topStart(to anchor: Anchor) -> PinLayoutObjC {
- impl?.topStart(to: anchor)
+ func topLeft() -> PinLayoutObjC {
+ _ = impl?.topLeft()
return self
}
- public func topStart() -> PinLayoutObjC {
- impl?.topStart()
+ func topStart(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.topStart(to: anchor)
return self
}
- public func topCenter(to anchor: Anchor) -> PinLayoutObjC {
- impl?.topCenter(to: anchor)
+ func topStart() -> PinLayoutObjC {
+ _ = impl?.topStart()
return self
}
- public func topCenter() -> PinLayoutObjC {
- impl?.topCenter()
+ func topCenter(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.topCenter(to: anchor)
return self
}
- public func topRight(to anchor: Anchor) -> PinLayoutObjC {
- impl?.topRight(to: anchor)
+ func topCenter() -> PinLayoutObjC {
+ _ = impl?.topCenter()
return self
}
- public func topRight() -> PinLayoutObjC {
- impl?.topRight()
+ func topRight(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.topRight(to: anchor)
return self
}
- public func topEnd(to anchor: Anchor) -> PinLayoutObjC {
- impl?.topEnd(to: anchor)
+ func topRight() -> PinLayoutObjC {
+ _ = impl?.topRight()
return self
}
- public func topEnd() -> PinLayoutObjC {
- impl?.topEnd()
+ func topEnd(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.topEnd(to: anchor)
return self
}
- public func centerLeft(to anchor: Anchor) -> PinLayoutObjC {
- impl?.centerLeft(to: anchor)
+ func topEnd() -> PinLayoutObjC {
+ _ = impl?.topEnd()
return self
}
- public func centerLeft() -> PinLayoutObjC {
- impl?.centerLeft()
+ func centerLeft(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.centerLeft(to: anchor)
return self
}
- public func centerStart(to anchor: Anchor) -> PinLayoutObjC {
- impl?.centerStart(to: anchor)
+ func centerLeft() -> PinLayoutObjC {
+ _ = impl?.centerLeft()
return self
}
- public func centerStart() -> PinLayoutObjC {
- impl?.centerStart()
+ func centerStart(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.centerStart(to: anchor)
return self
}
- public func center(to anchor: Anchor) -> PinLayoutObjC {
- impl?.center(to: anchor)
+ func centerStart() -> PinLayoutObjC {
+ _ = impl?.centerStart()
return self
}
- public func center() -> PinLayoutObjC {
- impl?.center()
+ func center(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.center(to: anchor)
return self
}
- public func centerRight(to anchor: Anchor) -> PinLayoutObjC {
- impl?.centerRight(to: anchor)
+ func center() -> PinLayoutObjC {
+ _ = impl?.center()
return self
}
- public func centerRight() -> PinLayoutObjC {
- impl?.centerRight()
+ func centerRight(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.centerRight(to: anchor)
return self
}
- public func centerEnd(to anchor: Anchor) -> PinLayoutObjC {
- impl?.centerEnd(to: anchor)
+ func centerRight() -> PinLayoutObjC {
+ _ = impl?.centerRight()
return self
}
- public func centerEnd() -> PinLayoutObjC {
- impl?.centerEnd()
+ func centerEnd(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.centerEnd(to: anchor)
return self
}
- public func bottomLeft(to anchor: Anchor) -> PinLayoutObjC {
- impl?.bottomLeft(to: anchor)
+ func centerEnd() -> PinLayoutObjC {
+ _ = impl?.centerEnd()
return self
}
- public func bottomLeft() -> PinLayoutObjC {
- impl?.bottomLeft()
+ func bottomLeft(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.bottomLeft(to: anchor)
return self
}
- public func bottomStart(to anchor: Anchor) -> PinLayoutObjC {
- impl?.bottomStart(to: anchor)
+ func bottomLeft() -> PinLayoutObjC {
+ _ = impl?.bottomLeft()
return self
}
- public func bottomStart() -> PinLayoutObjC {
- impl?.bottomStart()
+ func bottomStart(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.bottomStart(to: anchor)
return self
}
- public func bottomCenter(to anchor: Anchor) -> PinLayoutObjC {
- impl?.bottomCenter(to: anchor)
+ func bottomStart() -> PinLayoutObjC {
+ _ = impl?.bottomStart()
return self
}
- public func bottomCenter() -> PinLayoutObjC {
- impl?.bottomCenter()
+ func bottomCenter(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.bottomCenter(to: anchor)
return self
}
- public func bottomRight(to anchor: Anchor) -> PinLayoutObjC {
- impl?.bottomRight(to: anchor)
+ func bottomCenter() -> PinLayoutObjC {
+ _ = impl?.bottomCenter()
return self
}
- public func bottomRight() -> PinLayoutObjC {
- impl?.bottomRight()
+ func bottomRight(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.bottomRight(to: anchor)
return self
}
- public func bottomEnd(to anchor: Anchor) -> PinLayoutObjC {
- impl?.bottomEnd(to: anchor)
+ func bottomRight() -> PinLayoutObjC {
+ _ = impl?.bottomRight()
return self
}
- public func bottomEnd() -> PinLayoutObjC {
- impl?.bottomEnd()
+ func bottomEnd(to anchor: Anchor) -> PinLayoutObjC {
+ _ = impl?.bottomEnd(to: anchor)
return self
}
- public func above(of view: UIView) -> PinLayoutObjC {
- impl?.above(of: view)
+ func bottomEnd() -> PinLayoutObjC {
+ _ = impl?.bottomEnd()
return self
}
- public func above(ofViews views: [UIView]) -> PinLayoutObjC {
- impl?.above(of: views)
+ func above(of view: PView) -> PinLayoutObjC {
+ _ = impl?.above(of: view)
return self
}
- public func above(of view: UIView, aligned: HorizontalAlign) -> PinLayoutObjC {
- impl?.above(of: view, aligned: aligned)
+ func above(ofViews views: [PView]) -> PinLayoutObjC {
+ _ = impl?.above(of: views)
return self
}
- public func above(ofViews views: [UIView], aligned: HorizontalAlign) -> PinLayoutObjC {
- impl?.above(of: views, aligned: aligned)
+ func above(of view: PView, aligned: HorizontalAlign) -> PinLayoutObjC {
+ _ = impl?.above(of: view, aligned: aligned)
return self
}
- public func below(of view: UIView) -> PinLayoutObjC {
- impl?.below(of: view)
+ func above(ofViews views: [PView], aligned: HorizontalAlign) -> PinLayoutObjC {
+ _ = impl?.above(of: views, aligned: aligned)
return self
}
- public func below(ofViews views: [UIView]) -> PinLayoutObjC {
- impl?.below(of: views)
+ func below(of view: PView) -> PinLayoutObjC {
+ _ = impl?.below(of: view)
return self
}
- public func below(of view: UIView, aligned: HorizontalAlign) -> PinLayoutObjC {
- impl?.below(of: view, aligned: aligned)
+ func below(ofViews views: [PView]) -> PinLayoutObjC {
+ _ = impl?.below(of: views)
return self
}
- public func below(ofViews views: [UIView], aligned: HorizontalAlign) -> PinLayoutObjC {
- impl?.below(of: views, aligned: aligned)
+ func below(of view: PView, aligned: HorizontalAlign) -> PinLayoutObjC {
+ _ = impl?.below(of: view, aligned: aligned)
return self
}
- public func left(of view: UIView) -> PinLayoutObjC {
- impl?.left(of: view)
+ func below(ofViews views: [PView], aligned: HorizontalAlign) -> PinLayoutObjC {
+ _ = impl?.below(of: views, aligned: aligned)
return self
}
- public func left(ofViews views: [UIView]) -> PinLayoutObjC {
- impl?.left(of: views)
+ func left(of view: PView) -> PinLayoutObjC {
+ _ = impl?.left(of: view)
return self
}
- public func left(of view: UIView, aligned: VerticalAlign) -> PinLayoutObjC {
- impl?.left(of: view, aligned: aligned)
+ func left(ofViews views: [PView]) -> PinLayoutObjC {
+ _ = impl?.left(of: views)
return self
}
- public func left(ofViews views: [UIView], aligned: VerticalAlign) -> PinLayoutObjC {
- impl?.left(of: views, aligned: aligned)
+ func left(of view: PView, aligned: VerticalAlign) -> PinLayoutObjC {
+ _ = impl?.left(of: view, aligned: aligned)
return self
}
- public func right(of view: UIView) -> PinLayoutObjC {
- impl?.right(of: view)
+ func left(ofViews views: [PView], aligned: VerticalAlign) -> PinLayoutObjC {
+ _ = impl?.left(of: views, aligned: aligned)
return self
}
- public func right(ofViews views: [UIView]) -> PinLayoutObjC {
- impl?.right(of: views)
+ func right(of view: PView) -> PinLayoutObjC {
+ _ = impl?.right(of: view)
return self
}
- public func right(of view: UIView, aligned: VerticalAlign) -> PinLayoutObjC {
- impl?.right(of: view, aligned: aligned)
+ func right(ofViews views: [PView]) -> PinLayoutObjC {
+ _ = impl?.right(of: views)
return self
}
- public func right(ofViews views: [UIView], aligned: VerticalAlign) -> PinLayoutObjC {
- impl?.right(of: views, aligned: aligned)
+ func right(of view: PView, aligned: VerticalAlign) -> PinLayoutObjC {
+ _ = impl?.right(of: view, aligned: aligned)
return self
}
- public func before(of view: UIView) -> PinLayoutObjC {
- impl?.before(of: view)
+ func right(ofViews views: [PView], aligned: VerticalAlign) -> PinLayoutObjC {
+ _ = impl?.right(of: views, aligned: aligned)
return self
}
- public func before(ofViews views: [UIView]) -> PinLayoutObjC {
- impl?.before(of: views)
+ func before(of view: PView) -> PinLayoutObjC {
+ _ = impl?.before(of: view)
return self
}
- public func before(of view: UIView, aligned: VerticalAlign) -> PinLayoutObjC {
- impl?.before(of: view, aligned: aligned)
+ func before(ofViews views: [PView]) -> PinLayoutObjC {
+ _ = impl?.before(of: views)
return self
}
- public func before(ofViews views: [UIView], aligned: VerticalAlign) -> PinLayoutObjC {
- impl?.before(of: views, aligned: aligned)
+ func before(of view: PView, aligned: VerticalAlign) -> PinLayoutObjC {
+ _ = impl?.before(of: view, aligned: aligned)
return self
}
- public func after(of view: UIView) -> PinLayoutObjC {
- impl?.after(of: view)
+ func before(ofViews views: [PView], aligned: VerticalAlign) -> PinLayoutObjC {
+ _ = impl?.before(of: views, aligned: aligned)
return self
}
- public func after(ofViews views: [UIView]) -> PinLayoutObjC {
- impl?.after(of: views)
+ func after(of view: PView) -> PinLayoutObjC {
+ _ = impl?.after(of: view)
return self
}
- public func after(of view: UIView, aligned: VerticalAlign) -> PinLayoutObjC {
- impl?.after(of: view, aligned: aligned)
+ func after(ofViews views: [PView]) -> PinLayoutObjC {
+ _ = impl?.after(of: views)
return self
}
- public func after(ofViews views: [UIView], aligned: VerticalAlign) -> PinLayoutObjC {
- impl?.after(of: views, aligned: aligned)
+ func after(of view: PView, aligned: VerticalAlign) -> PinLayoutObjC {
+ _ = impl?.after(of: view, aligned: aligned)
return self
}
- public func justify(_ align: HorizontalAlign) -> PinLayoutObjC {
- impl?.justify(align)
+ func after(ofViews views: [PView], aligned: VerticalAlign) -> PinLayoutObjC {
+ _ = impl?.after(of: views, aligned: aligned)
return self
}
- public func align(_ align: VerticalAlign) -> PinLayoutObjC {
- impl?.align(align)
+ func justify(_ align: HorizontalAlign) -> PinLayoutObjC {
+ _ = impl?.justify(align)
return self
}
- public func width(_ width: CGFloat) -> PinLayoutObjC {
- impl?.width(width)
+ func align(_ align: VerticalAlign) -> PinLayoutObjC {
+ _ = impl?.align(align)
return self
}
- public func width(percent: CGFloat) -> PinLayoutObjC {
- impl?.width(percent%)
+ func width(_ width: CGFloat) -> PinLayoutObjC {
+ _ = impl?.width(width)
return self
}
- public func width(of view: UIView) -> PinLayoutObjC {
- impl?.width(of: view)
+ func width(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.width(percent%)
return self
}
- public func minWidth(_ width: CGFloat) -> PinLayoutObjC {
- impl?.minWidth(width)
+ func width(of view: PView) -> PinLayoutObjC {
+ _ = impl?.width(of: view)
return self
}
- public func minWidth(percent: CGFloat) -> PinLayoutObjC {
- impl?.minWidth(percent%)
+ func minWidth(_ width: CGFloat) -> PinLayoutObjC {
+ _ = impl?.minWidth(width)
return self
}
- public func maxWidth(_ width: CGFloat) -> PinLayoutObjC {
- impl?.maxWidth(width)
+ func minWidth(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.minWidth(percent%)
return self
}
- public func maxWidth(percent: CGFloat) -> PinLayoutObjC {
- impl?.maxWidth(percent%)
+ func maxWidth(_ width: CGFloat) -> PinLayoutObjC {
+ _ = impl?.maxWidth(width)
return self
}
- public func height(_ height: CGFloat) -> PinLayoutObjC {
- impl?.height(height)
+ func maxWidth(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.maxWidth(percent%)
return self
}
- public func height(percent: CGFloat) -> PinLayoutObjC {
- impl?.height(percent%)
+ func height(_ height: CGFloat) -> PinLayoutObjC {
+ _ = impl?.height(height)
return self
}
- public func height(of view: UIView) -> PinLayoutObjC {
- impl?.height(of: view)
+ func height(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.height(percent%)
return self
}
- public func minHeight(_ height: CGFloat) -> PinLayoutObjC {
- impl?.minHeight(height)
+ func height(of view: PView) -> PinLayoutObjC {
+ _ = impl?.height(of: view)
return self
}
- public func minHeight(percent: CGFloat) -> PinLayoutObjC {
- impl?.minHeight(percent%)
+ func minHeight(_ height: CGFloat) -> PinLayoutObjC {
+ _ = impl?.minHeight(height)
return self
}
- public func maxHeight(_ height: CGFloat) -> PinLayoutObjC {
- impl?.maxHeight(height)
+ func minHeight(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.minHeight(percent%)
return self
}
- public func maxHeight(percent: CGFloat) -> PinLayoutObjC {
- impl?.maxHeight(percent%)
+ func maxHeight(_ height: CGFloat) -> PinLayoutObjC {
+ _ = impl?.maxHeight(height)
return self
}
- public func size(_ size: CGSize) -> PinLayoutObjC {
- impl?.size(size)
+ func maxHeight(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.maxHeight(percent%)
return self
}
- public func size(length: CGFloat) -> PinLayoutObjC {
- impl?.size(length)
+ func size(_ size: CGSize) -> PinLayoutObjC {
+ _ = impl?.size(size)
return self
}
- public func size(percent: CGFloat) -> PinLayoutObjC {
- impl?.size(percent%)
+ func size(length: CGFloat) -> PinLayoutObjC {
+ _ = impl?.size(length)
return self
}
- public func size(of view: UIView) -> PinLayoutObjC {
- impl?.size(of: view)
+ func size(percent: CGFloat) -> PinLayoutObjC {
+ _ = impl?.size(percent%)
return self
}
- public func aspectRatio(_ ratio: CGFloat) -> PinLayoutObjC {
- impl?.aspectRatio(ratio)
+ func size(of view: PView) -> PinLayoutObjC {
+ _ = impl?.size(of: view)
return self
}
- public func aspectRatio(of view: UIView) -> PinLayoutObjC {
- impl?.aspectRatio(of: view)
+ func aspectRatio(_ ratio: CGFloat) -> PinLayoutObjC {
+ _ = impl?.aspectRatio(ratio)
return self
}
- public func aspectRatio() -> PinLayoutObjC {
- impl?.aspectRatio()
+ func aspectRatio(of view: PView) -> PinLayoutObjC {
+ _ = impl?.aspectRatio(of: view)
return self
}
-
- public func fitSize() -> PinLayoutObjC {
- impl?.fitSize()
+
+ #if os(iOS) || os(tvOS)
+ func aspectRatio() -> PinLayoutObjC {
+ _ = impl?.aspectRatio()
return self
}
-
- public func sizeToFit(_ fitType: Fit) -> PinLayoutObjC {
+ #endif
+
+ func sizeToFit(_ fitType: Fit) -> PinLayoutObjC {
let type: FitType
switch fitType {
case .width: type = .width
@@ -623,79 +623,77 @@ import UIKit
case .widthFlexible: type = .widthFlexible
case .heightFlexible: type = .heightFlexible
}
- impl?.sizeToFit(type)
+ _ = impl?.sizeToFit(type)
return self
}
- public func marginTop(_ value: CGFloat) -> PinLayoutObjC {
- impl?.marginTop(value)
+ func marginTop(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.marginTop(value)
return self
}
- public func marginLeft(_ value: CGFloat) -> PinLayoutObjC {
- impl?.marginLeft(value)
+ func marginLeft(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.marginLeft(value)
return self
}
- public func marginBottom(_ value: CGFloat) -> PinLayoutObjC {
- impl?.marginBottom(value)
+ func marginBottom(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.marginBottom(value)
return self
}
- public func marginRight(_ value: CGFloat) -> PinLayoutObjC {
- impl?.marginRight(value)
+ func marginRight(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.marginRight(value)
return self
}
- public func marginStart(_ value: CGFloat) -> PinLayoutObjC {
- impl?.marginStart(value)
+ func marginStart(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.marginStart(value)
return self
}
- public func marginEnd(_ value: CGFloat) -> PinLayoutObjC {
- impl?.marginEnd(value)
+ func marginEnd(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.marginEnd(value)
return self
}
- public func marginHorizontal(_ value: CGFloat) -> PinLayoutObjC {
- impl?.marginHorizontal(value)
+ func marginHorizontal(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.marginHorizontal(value)
return self
}
- public func marginVertical(_ value: CGFloat) -> PinLayoutObjC {
- impl?.marginVertical(value)
+ func marginVertical(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.marginVertical(value)
return self
}
- public func margin(insets: UIEdgeInsets) -> PinLayoutObjC {
- impl?.margin(insets)
+ func margin(insets: PEdgeInsets) -> PinLayoutObjC {
+ _ = impl?.margin(insets)
return self
}
- public func margin(_ value: CGFloat) -> PinLayoutObjC {
- impl?.margin(value)
+ func margin(_ value: CGFloat) -> PinLayoutObjC {
+ _ = impl?.margin(value)
return self
}
- public func margin(vertical: CGFloat, horizontal: CGFloat) -> PinLayoutObjC {
- impl?.margin(vertical, horizontal)
+ func margin(vertical: CGFloat, horizontal: CGFloat) -> PinLayoutObjC {
+ _ = impl?.margin(vertical, horizontal)
return self
}
- public func margin(top: CGFloat, horizontal: CGFloat, bottom: CGFloat) -> PinLayoutObjC {
- impl?.margin(top, horizontal, bottom)
+ func margin(top: CGFloat, horizontal: CGFloat, bottom: CGFloat) -> PinLayoutObjC {
+ _ = impl?.margin(top, horizontal, bottom)
return self
}
- public func margin(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> PinLayoutObjC {
- impl?.margin(top, left, bottom, right)
+ func margin(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> PinLayoutObjC {
+ _ = impl?.margin(top, left, bottom, right)
return self
}
- public func pinEdges() -> PinLayoutObjC {
- impl?.pinEdges()
+ func pinEdges() -> PinLayoutObjC {
+ _ = impl?.pinEdges()
return self
}
}
-
-#endif
diff --git a/Sources/UIView+PinLayout.swift b/Sources/UIView+PinLayout.swift
index eca85485..c99c394b 100644
--- a/Sources/UIView+PinLayout.swift
+++ b/Sources/UIView+PinLayout.swift
@@ -27,5 +27,10 @@ public extension UIView {
@objc public var edge: EdgeList {
return EdgeListImpl(view: self)
}
+
+ // Expose PinLayout's objective-c interface.
+ @objc public var pinObjc: PinLayoutObjC {
+ return PinLayoutObjCImpl(view: self, keepTransform: true)
+ }
}
#endif
From 01347f1c5c02e6f6aaa21232cafa704836cd99cd Mon Sep 17 00:00:00 2001
From: Luc Dion
Date: Fri, 25 May 2018 20:59:18 -0400
Subject: [PATCH 002/389] Update
---
.../ios/PinLayout-iOS/TestObjectiveC.m | 2 +-
build-ci.sh | 88 +++++++++----------
2 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/TestProjects/cocoapods/ios/PinLayout-iOS/TestObjectiveC.m b/TestProjects/cocoapods/ios/PinLayout-iOS/TestObjectiveC.m
index 636fb5fd..1491dd1a 100644
--- a/TestProjects/cocoapods/ios/PinLayout-iOS/TestObjectiveC.m
+++ b/TestProjects/cocoapods/ios/PinLayout-iOS/TestObjectiveC.m
@@ -54,7 +54,7 @@ - (void) layoutSubviews {
[[[[[[logo.pinObjc top] left] width:100] aspectRatio] marginWithTop:topLayoutGuide + 10 horizontal:10 bottom:10] layout];
[[[[segmented.pinObjc rightOf:logo aligned:VerticalAlignTop] right] marginHorizontal:10] layout];
- [[[[[[textLabel.pinObjc belowOf:segmented aligned:HorizontalAlignLeft] widthOf:segmented] pinEdges] marginTop:10] fitSize] layout];
+ [[[[[[textLabel.pinObjc belowOf:segmented aligned:HorizontalAlignLeft] widthOf:segmented] pinEdges] marginTop:10] sizeToFit:FitWidth] layout];
[[[[[separatorView.pinObjc belowOfViews:@[logo, textLabel] aligned:HorizontalAlignLeft] rightTo:segmented.edge.right] height:1] marginTop:10] layout];
}
diff --git a/build-ci.sh b/build-ci.sh
index 429830f0..3f858b41 100755
--- a/build-ci.sh
+++ b/build-ci.sh
@@ -8,65 +8,65 @@ rm -rf $DERIVED_DATA &&
echo "===============================" &&
echo "fastlane iOS travis" &&
echo "===============================" &&
-time bundle exec fastlane ios travis &&
+# time bundle exec fastlane ios travis &&
# echo "===============================" &&
# echo "fastlane macOS travis" &&
# echo "===============================" &&
-# #time bundle exec fastlane mac travis &&
+# time bundle exec fastlane mac travis &&
-# echo "===============================" &&
-# echo "iOS unit test" &&
-# echo "===============================" &&
-# time xcodebuild build test -workspace PinLayout.xcworkspace -scheme PinLayout-iOS -derivedDataPath $DERIVED_DATA -sdk iphonesimulator11.3 \
-# -destination 'platform=iOS Simulator,name=iPhone 7 Plus,OS=11.3' \
-# -destination 'platform=iOS Simulator,name=iPhone 7,OS=11.3' \
-# -destination 'platform=iOS Simulator,name=iPhone 6,OS=10.2'\
-# | xcpretty &&
+echo "===============================" &&
+echo "iOS unit test" &&
+echo "===============================" &&
+time xcodebuild build test -workspace PinLayout.xcworkspace -scheme PinLayout-iOS -derivedDataPath $DERIVED_DATA -sdk iphonesimulator11.3 \
+ -destination 'platform=iOS Simulator,name=iPhone 7 Plus,OS=11.3' \
+ -destination 'platform=iOS Simulator,name=iPhone 7,OS=11.3' \
+ -destination 'platform=iOS Simulator,name=iPhone 6,OS=10.2'\
+ | xcpretty &&
-# echo "===============================" &&
-# echo "macOS unit test" &&
-# echo "===============================" &&
-# time xcodebuild clean test -workspace PinLayout.xcworkspace -scheme PinLayout-macOS -derivedDataPath $DERIVED_DATA -sdk macosx10.13 \
-# | xcpretty
+echo "===============================" &&
+echo "macOS unit test" &&
+echo "===============================" &&
+time xcodebuild clean test -workspace PinLayout.xcworkspace -scheme PinLayout-macOS -derivedDataPath $DERIVED_DATA -sdk macosx10.13 \
+ | xcpretty
-# echo "===============================" &&
-# echo " Cocoapods: iOS Empty project" &&
-# echo "===============================" &&
-# cd TestProjects/cocoapods/ios &&
-# rm -rf $DERIVED_DATA &&
-# pod install &&
-# time xcodebuild clean build -workspace PinLayout-iOS.xcworkspace -scheme PinLayout-iOS -sdk iphonesimulator11.3 -derivedDataPath $DERIVED_DATA \
-# -destination 'platform=iOS Simulator,name=iPhone 7,OS=11.3' \
-# | xcpretty &&
-# cd ../../..
+echo "===============================" &&
+echo " Cocoapods: iOS Empty project" &&
+echo "===============================" &&
+cd TestProjects/cocoapods/ios &&
+rm -rf $DERIVED_DATA &&
+pod install &&
+time xcodebuild clean build -workspace PinLayout-iOS.xcworkspace -scheme PinLayout-iOS -sdk iphonesimulator11.3 -derivedDataPath $DERIVED_DATA \
+ -destination 'platform=iOS Simulator,name=iPhone 7,OS=11.3' \
+ | xcpretty &&
+cd ../../..
-# echo "===============================" &&
-# echo " Cocoapods: macOS Empty project" &&
-# echo "===============================" &&
-# cd TestProjects/cocoapods/macos &&
-# rm -rf $DERIVED_DATA &&
-# pod install &&
-# time xcodebuild clean build -workspace PinLayout-macOS.xcworkspace -scheme PinLayout-macOS -sdk macosx10.13 -derivedDataPath $DERIVED_DATA \
-# | xcpretty &&
-# cd ../../..
+echo "===============================" &&
+echo " Cocoapods: macOS Empty project" &&
+echo "===============================" &&
+cd TestProjects/cocoapods/macos &&
+rm -rf $DERIVED_DATA &&
+pod install &&
+time xcodebuild clean build -workspace PinLayout-macOS.xcworkspace -scheme PinLayout-macOS -sdk macosx10.13 -derivedDataPath $DERIVED_DATA \
+ | xcpretty &&
+cd ../../..
-# echo "===============================" &&
-# echo " Cocoapods: tvOS Empty project" &&
-# echo "===============================" &&
-# cd TestProjects/cocoapods/tvos &&
-# rm -rf $DERIVED_DATA &&
-# pod install &&
-# time xcodebuild clean build -workspace PinLayout-tvOS.xcworkspace -scheme PinLayout-tvOS -sdk appletvsimulator11.3 -derivedDataPath $DERIVED_DATA \
-# -destination 'platform=tvOS Simulator,name=Apple TV,OS=11.3' \
-# | xcpretty &&
-# cd ../../..
+echo "===============================" &&
+echo " Cocoapods: tvOS Empty project" &&
+echo "===============================" &&
+cd TestProjects/cocoapods/tvos &&
+rm -rf $DERIVED_DATA &&
+pod install &&
+time xcodebuild clean build -workspace PinLayout-tvOS.xcworkspace -scheme PinLayout-tvOS -sdk appletvsimulator11.3 -derivedDataPath $DERIVED_DATA \
+ -destination 'platform=tvOS Simulator,name=Apple TV,OS=11.3' \
+ | xcpretty &&
+cd ../../..
echo "===============================" &&
From 4c6d513af7cf2ec1c379797c81166c5cf9991865 Mon Sep 17 00:00:00 2001
From: Luc Dion
Date: Fri, 25 May 2018 21:18:20 -0400
Subject: [PATCH 003/389] Update travis
---
.../carthage/ios/PinLayout-Carthage-iOS/TestObjectiveC.m | 2 +-
build-ci.sh | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/TestProjects/carthage/ios/PinLayout-Carthage-iOS/TestObjectiveC.m b/TestProjects/carthage/ios/PinLayout-Carthage-iOS/TestObjectiveC.m
index 636fb5fd..1491dd1a 100644
--- a/TestProjects/carthage/ios/PinLayout-Carthage-iOS/TestObjectiveC.m
+++ b/TestProjects/carthage/ios/PinLayout-Carthage-iOS/TestObjectiveC.m
@@ -54,7 +54,7 @@ - (void) layoutSubviews {
[[[[[[logo.pinObjc top] left] width:100] aspectRatio] marginWithTop:topLayoutGuide + 10 horizontal:10 bottom:10] layout];
[[[[segmented.pinObjc rightOf:logo aligned:VerticalAlignTop] right] marginHorizontal:10] layout];
- [[[[[[textLabel.pinObjc belowOf:segmented aligned:HorizontalAlignLeft] widthOf:segmented] pinEdges] marginTop:10] fitSize] layout];
+ [[[[[[textLabel.pinObjc belowOf:segmented aligned:HorizontalAlignLeft] widthOf:segmented] pinEdges] marginTop:10] sizeToFit:FitWidth] layout];
[[[[[separatorView.pinObjc belowOfViews:@[logo, textLabel] aligned:HorizontalAlignLeft] rightTo:segmented.edge.right] height:1] marginTop:10] layout];
}
diff --git a/build-ci.sh b/build-ci.sh
index 3f858b41..7bf0b3ce 100755
--- a/build-ci.sh
+++ b/build-ci.sh
@@ -8,13 +8,13 @@ rm -rf $DERIVED_DATA &&
echo "===============================" &&
echo "fastlane iOS travis" &&
echo "===============================" &&
-# time bundle exec fastlane ios travis &&
+time bundle exec fastlane ios travis &&
# echo "===============================" &&
# echo "fastlane macOS travis" &&
# echo "===============================" &&
-# time bundle exec fastlane mac travis &&
+time bundle exec fastlane mac travis &&
echo "===============================" &&
From b2a59926fa7d3b46151b22c68b5a8422d7d36f26 Mon Sep 17 00:00:00 2001
From: Luc Dion
Date: Sat, 26 May 2018 08:56:03 -0400
Subject: [PATCH 004/389] Update version to 1.7.4
---
CHANGELOG.md | 10 +++++++++-
PinLayout.podspec | 2 +-
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fe0a9bb2..cc252f36 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,15 @@
# Change Log
-## [1.7.3](https://github.com/layoutBox/FlexLayout/releases/tag/1.7.2)
+## [1.7.4](https://github.com/layoutBox/FlexLayout/releases/tag/1.7.4)
+Released on 2018-05-26
+
+### Objective-C support for macOS and tvOS
+Add the support of Objective-C to macOS and tvOS.
+
+Added by [Luc Dion](https://github.com/lucdion) in Pull Request [#138](https://github.com/mirego/PinLayout/pull/138)
+
+## [1.7.3](https://github.com/layoutBox/FlexLayout/releases/tag/1.7.3)
Released on 2018-04-25
### Add few missing Objective-C Interface properties and methods
diff --git a/PinLayout.podspec b/PinLayout.podspec
index a1d570cd..27ea861a 100644
--- a/PinLayout.podspec
+++ b/PinLayout.podspec
@@ -8,7 +8,7 @@
Pod::Spec.new do |spec|
spec.name = "PinLayout"
- spec.version = "1.7.3"
+ spec.version = "1.7.4"
spec.summary = "Fast Swift Views layouting without auto layout. No magic, pure code, full control and blazing fast. [iOS/macOS/tvOS]"
spec.description = "Fast Swift Views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainable. [iOS/macOS/tvOS]"
spec.homepage = "https://mirego.github.io/PinLayout/"
From d395185f2ad1d4fe49c0e5b3c9e05a96d8c5d410 Mon Sep 17 00:00:00 2001
From: Luc Dion
Date: Sat, 26 May 2018 09:11:57 -0400
Subject: [PATCH 005/389] Add objective-c CI tests app for macOS and tvOS.
---
.gitignore | 7 ++-
.../PinLayout-macOS.xcodeproj/project.pbxproj | 12 ++++
.../PinLayout-macOS-Bridging-Header.h | 4 ++
.../macos/PinLayout-macOS/TestObjectiveC.m | 41 +++++++++++++
.../PinLayout-tvOS.xcodeproj/project.pbxproj | 12 ++++
.../PinLayout-tvOS-Bridging-Header.h | 4 ++
.../tvos/PinLayout-tvOS/TestObjectiveC.m | 61 +++++++++++++++++++
7 files changed, 139 insertions(+), 2 deletions(-)
create mode 100644 TestProjects/cocoapods/macos/PinLayout-macOS/PinLayout-macOS-Bridging-Header.h
create mode 100644 TestProjects/cocoapods/macos/PinLayout-macOS/TestObjectiveC.m
create mode 100644 TestProjects/cocoapods/tvos/PinLayout-tvOS/PinLayout-tvOS-Bridging-Header.h
create mode 100644 TestProjects/cocoapods/tvos/PinLayout-tvOS/TestObjectiveC.m
diff --git a/.gitignore b/.gitignore
index 0c4e7350..2325e32c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,9 @@ TestProjects/cocoapods/macos/PinLayout-macOS.xcworkspace/
TestProjects/cocoapods/macos/Podfile.lock
TestProjects/cocoapods/tvos/PinLayout-tvOS.xcworkspace/
TestProjects/cocoapods/tvos/Podfile.lock
-
TestProjects/carthage/ios/Cartfile.resolved
-TestProjects/carthage/ios/Carthage/
\ No newline at end of file
+TestProjects/carthage/ios/Carthage/
+
+TestProjects/swift-package-manager
+
+Example/PinLayoutExampleMacOS
\ No newline at end of file
diff --git a/TestProjects/cocoapods/macos/PinLayout-macOS.xcodeproj/project.pbxproj b/TestProjects/cocoapods/macos/PinLayout-macOS.xcodeproj/project.pbxproj
index f45370fa..953edf48 100644
--- a/TestProjects/cocoapods/macos/PinLayout-macOS.xcodeproj/project.pbxproj
+++ b/TestProjects/cocoapods/macos/PinLayout-macOS.xcodeproj/project.pbxproj
@@ -11,6 +11,7 @@
447D4B571EA571EC002FDFF4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 447D4B561EA571EC002FDFF4 /* Assets.xcassets */; };
D481169C663D06B9487BD94A /* Pods_PinLayout_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AD1FED5769AD72F9C3BA80B4 /* Pods_PinLayout_macOS.framework */; };
DF47E42B2088F8B2008599A2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF47E42A2088F8B2008599A2 /* Main.storyboard */; };
+ DFF222C520B9932600AC2A84 /* TestObjectiveC.m in Sources */ = {isa = PBXBuildFile; fileRef = DFF222C420B9932600AC2A84 /* TestObjectiveC.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -22,6 +23,8 @@
5ECB97E9B35D047EBF30646A /* Pods-PinLayout-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PinLayout-macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-PinLayout-macOS/Pods-PinLayout-macOS.release.xcconfig"; sourceTree = ""; };
AD1FED5769AD72F9C3BA80B4 /* Pods_PinLayout_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PinLayout_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DF47E42A2088F8B2008599A2 /* Main.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
+ DFF222BF20B9920E00AC2A84 /* PinLayout-macOS-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PinLayout-macOS-Bridging-Header.h"; sourceTree = ""; };
+ DFF222C420B9932600AC2A84 /* TestObjectiveC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestObjectiveC.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -69,6 +72,8 @@
447D4B561EA571EC002FDFF4 /* Assets.xcassets */,
447D4B5B1EA571EC002FDFF4 /* Info.plist */,
DF47E42A2088F8B2008599A2 /* Main.storyboard */,
+ DFF222C420B9932600AC2A84 /* TestObjectiveC.m */,
+ DFF222BF20B9920E00AC2A84 /* PinLayout-macOS-Bridging-Header.h */,
);
path = "PinLayout-macOS";
sourceTree = "";
@@ -116,6 +121,7 @@
TargetAttributes = {
447D4B4E1EA571EC002FDFF4 = {
CreatedOnToolsVersion = 8.3.1;
+ LastSwiftMigration = 0930;
ProvisioningStyle = Automatic;
};
};
@@ -195,6 +201,7 @@
buildActionMask = 2147483647;
files = (
447D4B531EA571EC002FDFF4 /* AppDelegate.swift in Sources */,
+ DFF222C520B9932600AC2A84 /* TestObjectiveC.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -298,12 +305,15 @@
baseConfigurationReference = 039104F30404DFF00E9EE3EC /* Pods-PinLayout-macOS.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "PinLayout-macOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_BUNDLE_IDENTIFIER = "com.mirego.project.PinLayout-macOS";
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "PinLayout-macOS/PinLayout-macOS-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
@@ -313,12 +323,14 @@
baseConfigurationReference = 5ECB97E9B35D047EBF30646A /* Pods-PinLayout-macOS.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "PinLayout-macOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_BUNDLE_IDENTIFIER = "com.mirego.project.PinLayout-macOS";
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "PinLayout-macOS/PinLayout-macOS-Bridging-Header.h";
SWIFT_VERSION = 3.0;
};
name = Release;
diff --git a/TestProjects/cocoapods/macos/PinLayout-macOS/PinLayout-macOS-Bridging-Header.h b/TestProjects/cocoapods/macos/PinLayout-macOS/PinLayout-macOS-Bridging-Header.h
new file mode 100644
index 00000000..1b2cb5d6
--- /dev/null
+++ b/TestProjects/cocoapods/macos/PinLayout-macOS/PinLayout-macOS-Bridging-Header.h
@@ -0,0 +1,4 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
diff --git a/TestProjects/cocoapods/macos/PinLayout-macOS/TestObjectiveC.m b/TestProjects/cocoapods/macos/PinLayout-macOS/TestObjectiveC.m
new file mode 100644
index 00000000..0b51decb
--- /dev/null
+++ b/TestProjects/cocoapods/macos/PinLayout-macOS/TestObjectiveC.m
@@ -0,0 +1,41 @@
+//
+// TestObjectiveC.m
+// PinLayoutPodTester
+//
+// Created by DION, Luc (MTL) on 2017-10-12.
+// Copyright Š 2017 Mirego. All rights reserved.
+//
+
+#import
+
+@import AppKit;
+@import PinLayout;
+
+@interface IntroObjectiveCView: NSView {
+}
+@end
+
+@implementation IntroObjectiveCView {
+ CGFloat topLayoutGuide;
+ NSImageView* logo;
+ NSView* separatorView;
+}
+
+- (id)initWithFrame:(CGRect)frame {
+ if ((self = [super initWithFrame:frame])) {
+ topLayoutGuide = 0;
+
+ logo = [[NSImageView alloc] init];
+ separatorView = [[NSView alloc] init];
+ }
+ return self;
+}
+
+- (void)layout {
+ [super layout];
+
+ [[[[[logo.pinObjc top] left] width:100] marginWithTop:topLayoutGuide + 10 horizontal:10 bottom:10] layout];
+ [[[[separatorView.pinObjc belowOfViews:logo aligned:HorizontalAlignLeft] height:1] marginTop:10] layout];
+}
+
+@end
diff --git a/TestProjects/cocoapods/tvos/PinLayout-tvOS.xcodeproj/project.pbxproj b/TestProjects/cocoapods/tvos/PinLayout-tvOS.xcodeproj/project.pbxproj
index 6bef9549..954c6d02 100644
--- a/TestProjects/cocoapods/tvos/PinLayout-tvOS.xcodeproj/project.pbxproj
+++ b/TestProjects/cocoapods/tvos/PinLayout-tvOS.xcodeproj/project.pbxproj
@@ -11,6 +11,7 @@
448160371EA5A76A00FBA809 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 448160361EA5A76A00FBA809 /* AppDelegate.swift */; };
DF4C0F5A2088FBAA00B4C060 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF4C0F592088FBAA00B4C060 /* Main.storyboard */; };
DF4C0F5C2088FBC300B4C060 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF4C0F5B2088FBC300B4C060 /* ViewController.swift */; };
+ DFF222C720B993A900AC2A84 /* TestObjectiveC.m in Sources */ = {isa = PBXBuildFile; fileRef = DFF222C620B993A900AC2A84 /* TestObjectiveC.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -22,6 +23,8 @@
779A6A4C5B9EC1AC279D6A24 /* libPods-PinLayout-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PinLayout-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
DF4C0F592088FBAA00B4C060 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
DF4C0F5B2088FBC300B4C060 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ DFF222BC20B991CF00AC2A84 /* PinLayout-tvOS-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PinLayout-tvOS-Bridging-Header.h"; sourceTree = ""; };
+ DFF222C620B993A900AC2A84 /* TestObjectiveC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestObjectiveC.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -60,7 +63,9 @@
448160361EA5A76A00FBA809 /* AppDelegate.swift */,
DF4C0F592088FBAA00B4C060 /* Main.storyboard */,
DF4C0F5B2088FBC300B4C060 /* ViewController.swift */,
+ DFF222C620B993A900AC2A84 /* TestObjectiveC.m */,
4481603F1EA5A76B00FBA809 /* Info.plist */,
+ DFF222BC20B991CF00AC2A84 /* PinLayout-tvOS-Bridging-Header.h */,
);
path = "PinLayout-tvOS";
sourceTree = "";
@@ -115,6 +120,7 @@
TargetAttributes = {
448160321EA5A76A00FBA809 = {
CreatedOnToolsVersion = 8.3.1;
+ LastSwiftMigration = 0930;
ProvisioningStyle = Automatic;
};
};
@@ -175,6 +181,7 @@
buildActionMask = 2147483647;
files = (
DF4C0F5C2088FBC300B4C060 /* ViewController.swift in Sources */,
+ DFF222C720B993A900AC2A84 /* TestObjectiveC.m in Sources */,
448160371EA5A76A00FBA809 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -279,11 +286,14 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 3ACDA03AB2AD6F178CB4A934 /* Pods-PinLayout-tvOS.debug.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_MODULES = YES;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "PinLayout-tvOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.mirego.project.PinLayout-tvOS";
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "PinLayout-tvOS/PinLayout-tvOS-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
@@ -292,11 +302,13 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 6D86E0FD61D49B5CC904E75C /* Pods-PinLayout-tvOS.release.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_MODULES = YES;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "PinLayout-tvOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.mirego.project.PinLayout-tvOS";
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "PinLayout-tvOS/PinLayout-tvOS-Bridging-Header.h";
SWIFT_VERSION = 3.0;
};
name = Release;
diff --git a/TestProjects/cocoapods/tvos/PinLayout-tvOS/PinLayout-tvOS-Bridging-Header.h b/TestProjects/cocoapods/tvos/PinLayout-tvOS/PinLayout-tvOS-Bridging-Header.h
new file mode 100644
index 00000000..1b2cb5d6
--- /dev/null
+++ b/TestProjects/cocoapods/tvos/PinLayout-tvOS/PinLayout-tvOS-Bridging-Header.h
@@ -0,0 +1,4 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
diff --git a/TestProjects/cocoapods/tvos/PinLayout-tvOS/TestObjectiveC.m b/TestProjects/cocoapods/tvos/PinLayout-tvOS/TestObjectiveC.m
new file mode 100644
index 00000000..1491dd1a
--- /dev/null
+++ b/TestProjects/cocoapods/tvos/PinLayout-tvOS/TestObjectiveC.m
@@ -0,0 +1,61 @@
+//
+// TestObjectiveC.m
+// PinLayoutPodTester
+//
+// Created by DION, Luc (MTL) on 2017-10-12.
+// Copyright Š 2017 Mirego. All rights reserved.
+//
+
+#import
+
+@import UIKit;
+@import PinLayout;
+
+@interface IntroObjectiveCView: UIView {
+}
+@end
+
+@implementation IntroObjectiveCView {
+ CGFloat topLayoutGuide;
+ UIImageView* logo;
+ UISegmentedControl* segmented;
+ UILabel* textLabel;
+ UIView* separatorView;
+}
+
+- (id)initWithFrame:(CGRect)frame {
+ if ((self = [super initWithFrame:frame])) {
+ topLayoutGuide = 0;
+ self.backgroundColor = UIColor.whiteColor;
+
+ logo = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"PinLayout-logo" inBundle:nil compatibleWithTraitCollection:nil]];
+ [self addSubview:logo];
+
+ segmented = [[UISegmentedControl alloc] initWithItems: @[@"Intro", @"1", @"2"]];
+ [self addSubview:segmented];
+
+ textLabel = [[UILabel alloc] init];
+ textLabel.text = @"Swift manual views layouting without auto layout, no magic, pure code, full control. Concise syntax, readable & chainable.\n\nSwift manual views layouting without auto layout, no magic, pure code, full control. Concise syntax, readable & chainable.";
+ textLabel.font = [UIFont systemFontOfSize:14];
+ textLabel.numberOfLines = 0;
+ textLabel.lineBreakMode = NSLineBreakByWordWrapping;
+ [self addSubview:textLabel];
+
+ separatorView = [[UIView alloc] init];
+ separatorView.backgroundColor = UIColor.grayColor;
+
+ [self addSubview:separatorView];
+ }
+ return self;
+}
+
+- (void) layoutSubviews {
+ [super layoutSubviews];
+
+ [[[[[[logo.pinObjc top] left] width:100] aspectRatio] marginWithTop:topLayoutGuide + 10 horizontal:10 bottom:10] layout];
+ [[[[segmented.pinObjc rightOf:logo aligned:VerticalAlignTop] right] marginHorizontal:10] layout];
+ [[[[[[textLabel.pinObjc belowOf:segmented aligned:HorizontalAlignLeft] widthOf:segmented] pinEdges] marginTop:10] sizeToFit:FitWidth] layout];
+ [[[[[separatorView.pinObjc belowOfViews:@[logo, textLabel] aligned:HorizontalAlignLeft] rightTo:segmented.edge.right] height:1] marginTop:10] layout];
+}
+
+@end
From df8c01032b34a913d04ac65a19d234fb24cfa3de Mon Sep 17 00:00:00 2001
From: Luc Dion
Date: Fri, 1 Jun 2018 08:45:20 -0400
Subject: [PATCH 006/389] Update README.md
---
README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index ed4777cd..f4803bed 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@
+
@@ -15,12 +16,12 @@
-
+
From 666ba1a9cf088b98eaf848d65c8aa41b26f39729 Mon Sep 17 00:00:00 2001
From: Luc Dion
Date: Sun, 27 May 2018 07:44:36 -0400
Subject: [PATCH 007/389] Initial commit
---
Example/.swiftlint.yml | 1 +
PinLayout.xcodeproj/project.pbxproj | 40 ++-
.../contents.xcworkspacedata | 3 -
Podfile.lock | 4 +-
Sources/Filters.swift | 28 +++
Sources/Impl/PinLayoutImpl+Layouting.swift | 2 +-
Sources/Impl/PinLayoutImpl+WrapContent.swift | 98 ++++++++
Sources/Impl/PinLayoutImpl.swift | 16 +-
Sources/Impl/TypesImpl.swift | 41 ----
Sources/Pin.swift | 18 --
Sources/PinLayout.swift | 153 +-----------
Sources/Types+Description.swift | 62 +++++
Sources/Types.swift | 229 ++++++++++++++++++
Sources/UIView+PinLayout.swift | 1 +
Tests/Common/WrapContentSpec.swift | 216 +++++++++++++++++
15 files changed, 679 insertions(+), 233 deletions(-)
create mode 100644 Sources/Filters.swift
create mode 100644 Sources/Impl/PinLayoutImpl+WrapContent.swift
create mode 100644 Sources/Types+Description.swift
create mode 100644 Sources/Types.swift
create mode 100644 Tests/Common/WrapContentSpec.swift
diff --git a/Example/.swiftlint.yml b/Example/.swiftlint.yml
index 0df8a810..adee2693 100644
--- a/Example/.swiftlint.yml
+++ b/Example/.swiftlint.yml
@@ -24,3 +24,4 @@ disabled_rules: # rule identifiers to exclude from running
excluded: # paths to ignore during linting. overridden by `included`.
- Pods
+ - PinLayoutExampleMacOS
\ No newline at end of file
diff --git a/PinLayout.xcodeproj/project.pbxproj b/PinLayout.xcodeproj/project.pbxproj
index 4dcefc0d..d8a6f080 100644
--- a/PinLayout.xcodeproj/project.pbxproj
+++ b/PinLayout.xcodeproj/project.pbxproj
@@ -47,9 +47,9 @@
2482908C1E78CFFC00667D08 /* RelativePositionSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2482908B1E78CFFC00667D08 /* RelativePositionSpec.swift */; };
248E4C741F7A883800C0E7F7 /* AspectRatioTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 248E4C721F7A83FA00C0E7F7 /* AspectRatioTests.swift */; };
248E4C771F7A88D200C0E7F7 /* UIImage+Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 248E4C751F7A88CF00C0E7F7 /* UIImage+Color.swift */; };
- 24949A2E1EF69474003643D3 /* PinLayout+Filters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24949A2D1EF69474003643D3 /* PinLayout+Filters.swift */; };
+ 24949A2E1EF69474003643D3 /* Filters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24949A2D1EF69474003643D3 /* Filters.swift */; };
249EFE841E64FB4C00165E39 /* PinLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 249EFE7A1E64FB4C00165E39 /* PinLayout.framework */; };
- 24B02B091F2A713000C18179 /* PinLayout+Filters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24949A2D1EF69474003643D3 /* PinLayout+Filters.swift */; };
+ 24B02B091F2A713000C18179 /* Filters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24949A2D1EF69474003643D3 /* Filters.swift */; };
24B02B0A1F2A713300C18179 /* PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC97CA61E8A8F2C001545D5 /* PinLayout.swift */; };
24D18D171F3B4381008129EF /* RTLSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D151F3B42E0008129EF /* RTLSpec.swift */; };
24D18D241F3E37DD008129EF /* Pin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D231F3E37DD008129EF /* Pin.swift */; };
@@ -62,7 +62,7 @@
DF1A5D352084CFC100725EF5 /* NSView+PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1A5CBC208106C900725EF5 /* NSView+PinLayout.swift */; };
DF1A5D362084CFC100725EF5 /* NSView+PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1A5CBC208106C900725EF5 /* NSView+PinLayout.swift */; };
DF1A5D372084CFC200725EF5 /* NSView+PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1A5CBC208106C900725EF5 /* NSView+PinLayout.swift */; };
- DF1A5D382084CFC600725EF5 /* PinLayout+Filters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24949A2D1EF69474003643D3 /* PinLayout+Filters.swift */; };
+ DF1A5D382084CFC600725EF5 /* Filters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24949A2D1EF69474003643D3 /* Filters.swift */; };
DF1A5D392084CFC600725EF5 /* Pin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D231F3E37DD008129EF /* Pin.swift */; };
DF1A5D3A2084CFC600725EF5 /* UIView+PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1A5CBA208106A900725EF5 /* UIView+PinLayout.swift */; };
DF1A5D3B2084CFD600725EF5 /* PinLayoutImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6C61FC37C1C0054CADD /* PinLayoutImpl.swift */; };
@@ -106,6 +106,14 @@
DFF222B220B877F600AC2A84 /* PinLayoutObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 241A277B1F8E958F00B1AD39 /* PinLayoutObjC.swift */; };
DFF222B320B877F800AC2A84 /* PinLayoutObjCImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 241A277C1F8E958F00B1AD39 /* PinLayoutObjCImpl.swift */; };
DFF222B420B877F900AC2A84 /* PinLayoutObjCImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 241A277C1F8E958F00B1AD39 /* PinLayoutObjCImpl.swift */; };
+ DFF222C920B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222C820B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift */; };
+ DFF222CA20B9994200AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222C820B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift */; };
+ DFF222CB20B9994300AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222C820B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift */; };
+ DFF222CD20B999BD00AC2A84 /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222CC20B999BD00AC2A84 /* Types.swift */; };
+ DFF222CF20B99A6600AC2A84 /* Types+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222CE20B99A6600AC2A84 /* Types+Description.swift */; };
+ DFF222E320BACBBF00AC2A84 /* WrapContentSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222E120BACBA800AC2A84 /* WrapContentSpec.swift */; };
+ DFF222E420BACBC000AC2A84 /* WrapContentSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222E120BACBA800AC2A84 /* WrapContentSpec.swift */; };
+ DFF222E520BACBC000AC2A84 /* WrapContentSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222E120BACBA800AC2A84 /* WrapContentSpec.swift */; };
DFF6F9C72084DCD3004F5AED /* PinLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 244DF2F81EF46C500090508B /* PinLayout.framework */; };
DFF6F9CD2084E15A004F5AED /* BasicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C5011E75D88500073BEE /* BasicView.swift */; };
DFF6F9CE2084E15A004F5AED /* AdjustSizeSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C4FF1E75D74000073BEE /* AdjustSizeSpec.swift */; };
@@ -188,7 +196,7 @@
2482908B1E78CFFC00667D08 /* RelativePositionSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RelativePositionSpec.swift; sourceTree = ""; };
248E4C721F7A83FA00C0E7F7 /* AspectRatioTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AspectRatioTests.swift; sourceTree = ""; };
248E4C751F7A88CF00C0E7F7 /* UIImage+Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Color.swift"; sourceTree = ""; };
- 24949A2D1EF69474003643D3 /* PinLayout+Filters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PinLayout+Filters.swift"; sourceTree = ""; };
+ 24949A2D1EF69474003643D3 /* Filters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Filters.swift; sourceTree = ""; };
249EFE7A1E64FB4C00165E39 /* PinLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PinLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; };
249EFE831E64FB4C00165E39 /* PinLayoutTests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "PinLayoutTests-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
249EFE8A1E64FB4C00165E39 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Common/Info.plist; sourceTree = ""; };
@@ -216,6 +224,10 @@
DFB3ECB02061602E005F226B /* PinSafeArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PinSafeArea.swift; path = Impl/PinSafeArea.swift; sourceTree = ""; };
DFC97CA61E8A8F2C001545D5 /* PinLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PinLayout.swift; sourceTree = ""; };
DFCA5F1420111BCF00180CD7 /* UIScrollViewSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIScrollViewSpec.swift; sourceTree = ""; };
+ DFF222C820B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "PinLayoutImpl+WrapContent.swift"; path = "Impl/PinLayoutImpl+WrapContent.swift"; sourceTree = ""; };
+ DFF222CC20B999BD00AC2A84 /* Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = ""; };
+ DFF222CE20B99A6600AC2A84 /* Types+Description.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Types+Description.swift"; sourceTree = ""; };
+ DFF222E120BACBA800AC2A84 /* WrapContentSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WrapContentSpec.swift; sourceTree = ""; };
DFF6F9C22084DCD3004F5AED /* PinLayoutTests-tvOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "PinLayoutTests-tvOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@@ -327,9 +339,10 @@
249EFE7C1E64FB4C00165E39 /* Sources */ = {
isa = PBXGroup;
children = (
+ 24949A2D1EF69474003643D3 /* Filters.swift */,
DFC97CA61E8A8F2C001545D5 /* PinLayout.swift */,
- 24949A2D1EF69474003643D3 /* PinLayout+Filters.swift */,
24D18D231F3E37DD008129EF /* Pin.swift */,
+ DFF222CC20B999BD00AC2A84 /* Types.swift */,
DF1A5CBA208106A900725EF5 /* UIView+PinLayout.swift */,
DF1A5CBC208106C900725EF5 /* NSView+PinLayout.swift */,
DFA06B031E8B38B300B6D5E7 /* Impl */,
@@ -382,10 +395,12 @@
2475B6C41FC37A900054CADD /* PinLayoutImpl+Layouting.swift */,
2475B6C91FC37C1C0054CADD /* PinLayoutImpl+Relative.swift */,
2475B6C81FC37C1C0054CADD /* PinLayoutImpl+Warning.swift */,
+ DFF222C820B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift */,
DFB3ECB02061602E005F226B /* PinSafeArea.swift */,
2475B6D21FC37CD40054CADD /* Coordinates.swift */,
243C620E1FC3834B0082C327 /* Percent.swift */,
2475B6CE1FC37C570054CADD /* TypesImpl.swift */,
+ DFF222CE20B99A6600AC2A84 /* Types+Description.swift */,
2475B6D01FC37C8C0054CADD /* UIView+LTR.swift */,
);
name = Impl;
@@ -407,6 +422,7 @@
2482908B1E78CFFC00667D08 /* RelativePositionSpec.swift */,
242E8DC11EED5982005935FB /* RelativePositionMultipleViewsSpec.swift */,
240F88BF1F0C1ED900280FC8 /* WarningSpec.swift */,
+ DFF222E120BACBA800AC2A84 /* WrapContentSpec.swift */,
);
path = Common;
sourceTree = "";
@@ -797,10 +813,11 @@
DF1A5D362084CFC100725EF5 /* NSView+PinLayout.swift in Sources */,
243C62041FC37F680082C327 /* PinLayoutImpl.swift in Sources */,
243C62071FC37F6C0082C327 /* PinLayoutImpl+Relative.swift in Sources */,
+ DFF222CB20B9994300AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */,
243B12BC1FC393580072A9C3 /* Percent.swift in Sources */,
DFB3ECB72062A937005F226B /* PinSafeArea.swift in Sources */,
DF1A5D0420812DE100725EF5 /* UIView+PinLayout.swift in Sources */,
- 24B02B091F2A713000C18179 /* PinLayout+Filters.swift in Sources */,
+ 24B02B091F2A713000C18179 /* Filters.swift in Sources */,
24B02B0A1F2A713300C18179 /* PinLayout.swift in Sources */,
243C620B1FC37F6C0082C327 /* UIView+LTR.swift in Sources */,
243C62091FC37F6C0082C327 /* Coordinates.swift in Sources */,
@@ -816,11 +833,14 @@
files = (
24D18D241F3E37DD008129EF /* Pin.swift in Sources */,
2475B6CA1FC37C1C0054CADD /* PinLayoutImpl.swift in Sources */,
+ DFF222CF20B99A6600AC2A84 /* Types+Description.swift in Sources */,
241A277E1F8E958F00B1AD39 /* PinLayoutObjCImpl.swift in Sources */,
DF1A5D372084CFC200725EF5 /* NSView+PinLayout.swift in Sources */,
+ DFF222CD20B999BD00AC2A84 /* Types.swift in Sources */,
243C620F1FC3834B0082C327 /* Percent.swift in Sources */,
2475B6CB1FC37C1C0054CADD /* PinLayoutImpl+Coordinates.swift in Sources */,
2475B6C51FC37A900054CADD /* PinLayoutImpl+Layouting.swift in Sources */,
+ DFF222C920B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */,
2475B6CF1FC37C570054CADD /* TypesImpl.swift in Sources */,
2475B6D11FC37C8C0054CADD /* UIView+LTR.swift in Sources */,
DFC97CA71E8A8F2C001545D5 /* PinLayout.swift in Sources */,
@@ -828,7 +848,7 @@
DF1A5CBB208106A900725EF5 /* UIView+PinLayout.swift in Sources */,
2475B6D31FC37CD40054CADD /* Coordinates.swift in Sources */,
241A277D1F8E958F00B1AD39 /* PinLayoutObjC.swift in Sources */,
- 24949A2E1EF69474003643D3 /* PinLayout+Filters.swift in Sources */,
+ 24949A2E1EF69474003643D3 /* Filters.swift in Sources */,
DFB3ECB12061602F005F226B /* PinSafeArea.swift in Sources */,
2475B6CD1FC37C1C0054CADD /* PinLayoutImpl+Relative.swift in Sources */,
);
@@ -838,6 +858,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ DFF222E320BACBBF00AC2A84 /* WrapContentSpec.swift in Sources */,
240F88BE1F0C066800280FC8 /* JustifyAlignSpec.swift in Sources */,
2469C5001E75D74000073BEE /* AdjustSizeSpec.swift in Sources */,
243B12C81FC3D06F0072A9C3 /* LayoutMethodSpec.swift in Sources */,
@@ -872,6 +893,7 @@
DFED154F20852F7E009EF9A7 /* BasicView.swift in Sources */,
DFB288AF20854127001F9588 /* PinPointCoordinatesSpec.swift in Sources */,
DFB288A320853E82001F9588 /* JustifyAlignSpec.swift in Sources */,
+ DFF222E420BACBC000AC2A84 /* WrapContentSpec.swift in Sources */,
DFED15532085349A009EF9A7 /* RectNimbleMatcher.swift in Sources */,
DFB288B12085419B001F9588 /* RelativePositionSpec.swift in Sources */,
DFB288B2208541B7001F9588 /* RelativePositionMultipleViewsSpec.swift in Sources */,
@@ -897,11 +919,12 @@
DF1A5D412084CFD600725EF5 /* Coordinates.swift in Sources */,
DF1A5D422084CFD600725EF5 /* Percent.swift in Sources */,
DF1A5D3E2084CFD600725EF5 /* PinLayoutImpl+Relative.swift in Sources */,
+ DFF222CA20B9994200AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */,
DF1A5D442084CFD600725EF5 /* UIView+LTR.swift in Sources */,
DF1A5D352084CFC100725EF5 /* NSView+PinLayout.swift in Sources */,
DF1A5D3A2084CFC600725EF5 /* UIView+PinLayout.swift in Sources */,
DFED155120853085009EF9A7 /* PinLayout.swift in Sources */,
- DF1A5D382084CFC600725EF5 /* PinLayout+Filters.swift in Sources */,
+ DF1A5D382084CFC600725EF5 /* Filters.swift in Sources */,
DF1A5D392084CFC600725EF5 /* Pin.swift in Sources */,
DF1A5D3D2084CFD600725EF5 /* PinLayoutImpl+Layouting.swift in Sources */,
DF1A5D3C2084CFD600725EF5 /* PinLayoutImpl+Coordinates.swift in Sources */,
@@ -914,6 +937,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ DFF222E520BACBC000AC2A84 /* WrapContentSpec.swift in Sources */,
DFF6F9DC2084E15A004F5AED /* RelativePositionMultipleViewsSpec.swift in Sources */,
DFABC023208781EE00CB6494 /* Types+UIKit.swift in Sources */,
DFF6F9DB2084E15A004F5AED /* RelativePositionSpec.swift in Sources */,
diff --git a/PinLayout.xcworkspace/contents.xcworkspacedata b/PinLayout.xcworkspace/contents.xcworkspacedata
index 3be1104b..16192094 100644
--- a/PinLayout.xcworkspace/contents.xcworkspacedata
+++ b/PinLayout.xcworkspace/contents.xcworkspacedata
@@ -10,7 +10,4 @@
-
-
diff --git a/Podfile.lock b/Podfile.lock
index d8eb96e6..1c98d1a9 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -1,6 +1,6 @@
PODS:
- Nimble (7.0.3)
- - PinLayout (1.7.3)
+ - PinLayout (1.7.4)
- Quick (1.2.0)
- Reveal-SDK (10)
- SwiftLint (0.25.1)
@@ -25,7 +25,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
Nimble: 7f5a9c447a33002645a071bddafbfb24ea70e0ac
- PinLayout: 04488e8fc8d19b59760bdf99a16deff7bfac422d
+ PinLayout: e20545b1fd5110133e0b03bed61f196161af8b36
Quick: 58d203b1c5e27fff7229c4c1ae445ad7069a7a08
Reveal-SDK: 7869ddf1f902cabbb07a1f0dd06bd25861a126f7
SwiftLint: ce933681be10c3266e82576dad676fa815a602e9
diff --git a/Sources/Filters.swift b/Sources/Filters.swift
new file mode 100644
index 00000000..400ca72e
--- /dev/null
+++ b/Sources/Filters.swift
@@ -0,0 +1,28 @@
+// Copyright (c) 2017 Luc Dion
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#if os(iOS) || os(tvOS)
+import UIKit
+
+// Filter out all hidden views (isHidden is true or alpha is 0)
+public func visible(_ views: [UIView]) -> [UIView] {
+ return views.filter({ !$0.isHidden && $0.alpha > 0 })
+}
+
+#endif
diff --git a/Sources/Impl/PinLayoutImpl+Layouting.swift b/Sources/Impl/PinLayoutImpl+Layouting.swift
index 405bae96..367a4dc0 100644
--- a/Sources/Impl/PinLayoutImpl+Layouting.swift
+++ b/Sources/Impl/PinLayoutImpl+Layouting.swift
@@ -23,7 +23,7 @@
import AppKit
#endif
-// MARK - UIView's frame computation methods
+// MARK: UIView's frame computation methods
extension PinLayoutImpl {
public func layout() {
apply()
diff --git a/Sources/Impl/PinLayoutImpl+WrapContent.swift b/Sources/Impl/PinLayoutImpl+WrapContent.swift
new file mode 100644
index 00000000..06d2a928
--- /dev/null
+++ b/Sources/Impl/PinLayoutImpl+WrapContent.swift
@@ -0,0 +1,98 @@
+// Copyright (c) 2018 Luc Dion
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#if os(iOS) || os(tvOS)
+import UIKit
+#else
+import AppKit
+#endif
+
+extension PinLayoutImpl {
+ func wrapContent() -> PinLayout {
+ return wrapContent(.all, padding: .zero, { return "wrapContent()" })
+ }
+
+ func wrapContent(_ type: WrapType) -> PinLayout {
+ return wrapContent(type, padding: .zero, { return "wrapContent(\(type.description)" })
+ }
+
+ @discardableResult
+ private func wrapContent(_ type: WrapType, padding: PPadding, _ context: Context) -> PinLayout {
+ let subviews = view.subviews
+ guard !subviews.isEmpty else { return self }
+ let firstViewFrame = subviews[0].frame
+ var minX = firstViewFrame.minX
+ var maxX = firstViewFrame.maxX
+ var minY = firstViewFrame.minY
+ var maxY = firstViewFrame.maxY
+
+ for var i in 1.. maxX {
+ maxX = frame.maxX
+ }
+ if frame.minY < minY {
+ minY = frame.minY
+ }
+ if frame.maxY > maxY {
+ maxY = frame.maxY
+ }
+ }
+
+ var offsetDx: CGFloat = 0
+ var offsetDy: CGFloat = 0
+
+ if type == .all || type == .width {
+ let contentWidth = maxX - minX
+ if contentWidth >= 0 {
+ setWidth(contentWidth, context)
+ }
+
+ offsetDx = -minX
+// let contentWidth = view.subviews.max(by: { subview1, subview2 in
+// subview1.frame.maxX < subview2.frame.maxX
+// })?.frame.maxX ?? 0
+ }
+
+ if type == .all || type == .height {
+ let contentHeight = maxY - minY
+ if contentHeight >= 0 {
+ setHeight(contentHeight, context)
+ }
+
+ offsetDy = -minY
+// let contentHeight = view.subviews.max(by: { subview1, subview2 in
+// subview1.frame.maxY < subview2.frame.maxY
+// })?.frame.maxY ?? 0
+ }
+
+ if offsetDx != 0 || offsetDy != 0 {
+ subviews.forEach { (view) in
+ let viewRect = Coordinates.getViewRect(view, keepTransform: keepTransform)
+ let newRect = viewRect.offsetBy(dx: offsetDx, dy: offsetDy)
+ Coordinates.setViewRect(view, toRect: newRect, keepTransform: keepTransform)
+ }
+ }
+
+ return self
+ }
+}
diff --git a/Sources/Impl/PinLayoutImpl.swift b/Sources/Impl/PinLayoutImpl.swift
index ae01e5e9..2d07b3b8 100644
--- a/Sources/Impl/PinLayoutImpl.swift
+++ b/Sources/Impl/PinLayoutImpl.swift
@@ -728,14 +728,8 @@ class PinLayoutImpl: PinLayout {
func context() -> String { return "size(of \(viewDescription(view)))" }
return setSize(view.bounds.size, context)
}
-
-// func wrapSubViews() -> PinLayout {
-// let neededWidth = view.subviews.max(by: { subview1, subview2 in subview1.frame.maxX < subview2.frame.maxX })?.frame.maxX ?? 0
-// let neededHeight = view.subviews.max(by: { subview1, subview2 in subview1.frame.maxY < subview2.frame.maxY })?.frame.maxY ?? 0
-//
-// return setSize(CGSize(width: neededWidth, height: neededHeight), { return "wrapSubViews()" })
-// }
-
+
+ @discardableResult
func aspectRatio(_ ratio: CGFloat) -> PinLayout {
return setAspectRatio(ratio, context: { "aspectRatio(\(ratio))" })
}
@@ -761,7 +755,7 @@ class PinLayoutImpl: PinLayout {
#endif
func sizeToFit(_ fitType: FitType) -> PinLayout {
- return setFitSize(fitType: fitType, { return "sizeToFit(\(fitType.name))" })
+ return setFitSize(fitType: fitType, { return "sizeToFit(\(fitType.description))" })
}
#if os(iOS) || os(tvOS)
@@ -992,7 +986,7 @@ extension PinLayoutImpl {
} else if fitType != nil && legacyFitSize {
warn("PinLayout Conflict: \(context()) won't be applied since it conflicts with fitSize().")
} else if let currentFitType = self.fitType, currentFitType != fitType {
- warn("PinLayout Conflict: \(context()) won't be applied since it conflicts with sizeToFit(\(currentFitType.name)).")
+ warn("PinLayout Conflict: \(context()) won't be applied since it conflicts with sizeToFit(\(currentFitType.description)).")
} else {
if fitType == nil {
legacyFitSize = true
@@ -1006,7 +1000,7 @@ extension PinLayoutImpl {
@discardableResult
internal func setAspectRatio(_ ratio: CGFloat, context: Context) -> PinLayout {
if let fitType = fitType {
- warn("PinLayout Conflict: \(context()) won't be applied since it conflicts with sizeToFit(\(fitType.name)).")
+ warn("PinLayout Conflict: \(context()) won't be applied since it conflicts with sizeToFit(\(fitType.description)).")
} else if legacyFitSize {
warn("PinLayout Conflict: \(context()) won't be applied since it conflicts with fitSize().")
} else if ratio <= 0 {
diff --git a/Sources/Impl/TypesImpl.swift b/Sources/Impl/TypesImpl.swift
index eb1060d2..94526a7a 100644
--- a/Sources/Impl/TypesImpl.swift
+++ b/Sources/Impl/TypesImpl.swift
@@ -28,28 +28,6 @@ import Foundation
typealias Context = () -> String
typealias Size = (width: CGFloat?, height: CGFloat?)
-extension HorizontalAlign {
- var description: String {
- switch self {
- case .left: return "left"
- case .center: return "center"
- case .right: return "right"
- case .start: return "start"
- case .end: return "end"
- }
- }
-}
-
-extension VerticalAlign {
- var description: String {
- switch self {
- case .top: return "top"
- case .center: return "center"
- case .bottom: return "bottom"
- }
- }
-}
-
class EdgeListImpl: EdgeList {
internal let view: PView
@@ -185,26 +163,7 @@ class AnchorImpl: Anchor {
}
}
-extension CGFloat {
- public var description: String {
- if self.truncatingRemainder(dividingBy: 1) == 0.0 {
- return "\(Int(self))"
- } else {
- return "\(self)"
- }
- }
-}
-
internal extension FitType {
- var name: String {
- switch self {
- case .width: return ".width"
- case .height: return ".height"
- case .widthFlexible: return ".widthFlexible"
- case .heightFlexible: return ".heightFlexible"
- }
- }
-
var isFlexible: Bool {
return self == .widthFlexible || self == .heightFlexible
}
diff --git a/Sources/Pin.swift b/Sources/Pin.swift
index 30a33003..ca74db56 100644
--- a/Sources/Pin.swift
+++ b/Sources/Pin.swift
@@ -19,24 +19,6 @@
import Foundation
-@objc public enum LayoutDirection: Int {
- case auto
- case ltr
- case rtl
-}
-
-/// Control how PinLayout will calls `UIView.safeAreaInsetsDidChange` when the `UIView.pin.safeArea` change.
-/// This support is usefull only on iOS 8/9/10. On iOS 11 `UIView.safeAreaInsetsDidChange` is supported
-/// natively so this settings have no impact.
-@objc public enum PinSafeAreaInsetsDidChangeMode: Int {
- /// PinLayout won't call `UIView.safeAreaInsetsDidChange` on iOS 8/9/10.
- case disable
- /// PinLayout will call `UIView.safeAreaInsetsDidChange` only if the UIView implement the PinSafeAreaInsetsUpdate protocol.
- case optIn
- /// PinLayout will automatically calls `UIView.safeAreaInsetsDidChange` if the view has implemented this method.
- case always
-}
-
@objc public class Pin: NSObject {
@objc public static var layoutDirection = LayoutDirection.ltr
diff --git a/Sources/PinLayout.swift b/Sources/PinLayout.swift
index e456a11b..9a659ad9 100644
--- a/Sources/PinLayout.swift
+++ b/Sources/PinLayout.swift
@@ -23,85 +23,6 @@ import UIKit
import AppKit
#endif
-/*
- UIView's anchors point
- ======================
-
- topLeft topCenter topRight
- o-------------o--------------o
- | |
- | |
- | |
- | |
- | |
- | center |
- centerLeft o o o centerRight
- | |
- | |
- | |
- | |
- | |
- | |
- o-------------o--------------o
- bottomLeft bottomCenter bottomLeft
-
- */
-
-/// UIViews's anchor definition
-@objc public protocol Anchor {
-}
-
-/// UIViews's list of anchors.
-@objc public protocol AnchorList {
- var topLeft: Anchor { get }
- var topCenter: Anchor { get }
- var topRight: Anchor { get }
- var centerLeft: Anchor { get }
- var center: Anchor { get }
- var centerRight: Anchor { get }
- var bottomLeft: Anchor { get }
- var bottomCenter: Anchor { get }
- var bottomRight: Anchor { get }
-
- // RTL support
- var topStart: Anchor { get }
- var topEnd: Anchor { get }
- var centerStart: Anchor { get }
- var centerEnd: Anchor { get }
- var bottomStart: Anchor { get }
- var bottomEnd: Anchor { get }
-}
-
-/*
- UIView's Edges
- ======================
- top
- +-----------------+
- | |
- | |
- | hCenter |
- left | + | right
- | vCenter |
- | |
- | |
- +-----------------+
- bottom
-*/
-
-/// UIViews's list of edges
-@objc public protocol EdgeList {
- var top: VerticalEdge { get }
- var vCenter: VerticalEdge { get }
- var bottom: VerticalEdge { get }
- var left: HorizontalEdge { get }
- var hCenter: HorizontalEdge { get }
- var right: HorizontalEdge { get }
-
- // RTL support
- var start: HorizontalEdge { get }
- var end: HorizontalEdge { get }
-}
-
/// PinLayout interface
public protocol PinLayout {
@@ -387,8 +308,10 @@ public protocol PinLayout {
@discardableResult func size(of view: NSView) -> PinLayout
#endif
- // @discardableResult func wrapSubViews() -> PinLayout
- // @discardableResult func wrapSubViews(insets: UIEdgeInsets) -> PinLayout
+ @discardableResult func wrapContent() -> PinLayout
+ @discardableResult func wrapContent(_ type: WrapType) -> PinLayout
+ @discardableResult func wrapContent(padding: PPadding) -> PinLayout
+ @discardableResult func wrapContent(_ type: WrapType, padding: PPadding) -> PinLayout
/**
Set the view aspect ratio.
@@ -620,71 +543,3 @@ public protocol PinLayout {
*/
func layout()
}
-
-/// Horizontal alignment used with relative positionning methods: above(of relativeView:, aligned:), below(of relativeView:, aligned:)
-///
-/// - left: left aligned
-/// - center: center aligned
-/// - right: right aligned
-@objc public enum HorizontalAlign: Int {
- case left
- case center
- case right
-
- // RTL support
- case start
- case end
-}
-
-/// Vertical alignment used with relative positionning methods: left(of relativeView:, aligned:), right(of relativeView:, aligned:)
-///
-/// - top: top aligned
-/// - center: center aligned
-/// - bottom: bottom aligned
-@objc public enum VerticalAlign: Int {
- case top
- case center
- case bottom
-}
-
-/// UIView's horizontal edges (left/right) definition
-@objc public protocol HorizontalEdge {
-}
-
-/// UIView's vertical edges (top/bottom) definition
-@objc public protocol VerticalEdge {
-}
-
-public enum FitType {
- /**
- **Adjust the view's height** based on the reference width.
- * If properties related to the width have been pinned (e.g: width, left & right, margins),
- the **reference width will be determined by these properties**, else the **current view's width**
- will be used.
- * The resulting width will always **match the reference width**.
- */
- case width
- /**
- **Adjust the view's width** based on the reference height.
- * If properties related to the height have been pinned (e.g: height, top & bottom, margins),
- the reference height will be determined by these properties, else the **current view's height**
- will be used.
- * The resulting height will always **match the reference height*.
- */
- case height
-
- /**
- Similar to `.width`, except that PinLayout won't constrain the resulting width to
- match the reference width. The resulting width may be smaller of bigger depending on the view's
- sizeThatFits(..) method result. For example a single line UILabel may returns a smaller width if its
- string is smaller than the reference width.
- */
- case widthFlexible
- /**
- Similar to `.height`, except that PinLayout won't constrain the resulting height to
- match the reference height. The resulting height may be smaller of bigger depending on the view's
- sizeThatFits(..) method result.
- */
- case heightFlexible
-}
-
diff --git a/Sources/Types+Description.swift b/Sources/Types+Description.swift
new file mode 100644
index 00000000..28946b2a
--- /dev/null
+++ b/Sources/Types+Description.swift
@@ -0,0 +1,62 @@
+//
+// Types+Description.swift
+// PinLayout-iOS
+//
+// Created by Luc Dion on 2018-05-26.
+// Copyright Š 2018 mcswiftlayyout.mirego.com. All rights reserved.
+//
+
+import Foundation
+
+extension HorizontalAlign {
+ var description: String {
+ switch self {
+ case .left: return "left"
+ case .center: return "center"
+ case .right: return "right"
+ case .start: return "start"
+ case .end: return "end"
+ }
+ }
+}
+
+extension VerticalAlign {
+ var description: String {
+ switch self {
+ case .top: return "top"
+ case .center: return "center"
+ case .bottom: return "bottom"
+ }
+ }
+}
+
+extension CGFloat {
+ public var description: String {
+ if self.truncatingRemainder(dividingBy: 1) == 0.0 {
+ return "\(Int(self))"
+ } else {
+ return "\(self)"
+ }
+ }
+}
+
+extension FitType {
+ var description: String {
+ switch self {
+ case .width: return ".width"
+ case .height: return ".height"
+ case .widthFlexible: return ".widthFlexible"
+ case .heightFlexible: return ".heightFlexible"
+ }
+ }
+}
+
+extension WrapType {
+ var description: String {
+ switch self {
+ case .all: return ".all"
+ case .width: return ".width"
+ case .height: return ".height"
+ }
+ }
+}
diff --git a/Sources/Types.swift b/Sources/Types.swift
new file mode 100644
index 00000000..32f691c3
--- /dev/null
+++ b/Sources/Types.swift
@@ -0,0 +1,229 @@
+// Copyright (c) 2018 Luc Dion
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Foundation
+
+
+/*
+ UIView's anchors point
+ ======================
+
+ topLeft topCenter topRight
+ o-------------o--------------o
+ | |
+ | |
+ | |
+ | |
+ | |
+ | center |
+ centerLeft o o o centerRight
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ o-------------o--------------o
+ bottomLeft bottomCenter bottomLeft
+
+ */
+
+/// UIViews's anchor definition
+@objc public protocol Anchor {
+}
+
+/// UIViews's list of anchors.
+@objc public protocol AnchorList {
+ var topLeft: Anchor { get }
+ var topCenter: Anchor { get }
+ var topRight: Anchor { get }
+ var centerLeft: Anchor { get }
+ var center: Anchor { get }
+ var centerRight: Anchor { get }
+ var bottomLeft: Anchor { get }
+ var bottomCenter: Anchor { get }
+ var bottomRight: Anchor { get }
+
+ // RTL support
+ var topStart: Anchor { get }
+ var topEnd: Anchor { get }
+ var centerStart: Anchor { get }
+ var centerEnd: Anchor { get }
+ var bottomStart: Anchor { get }
+ var bottomEnd: Anchor { get }
+}
+
+/*
+ UIView's Edges
+ ======================
+ top
+ +-----------------+
+ | |
+ | |
+ | hCenter |
+ left | + | right
+ | vCenter |
+ | |
+ | |
+ +-----------------+
+ bottom
+ */
+
+/// UIViews's list of edges
+@objc public protocol EdgeList {
+ var top: VerticalEdge { get }
+ var vCenter: VerticalEdge { get }
+ var bottom: VerticalEdge { get }
+ var left: HorizontalEdge { get }
+ var hCenter: HorizontalEdge { get }
+ var right: HorizontalEdge { get }
+
+ // RTL support
+ var start: HorizontalEdge { get }
+ var end: HorizontalEdge { get }
+}
+
+/// Horizontal alignment used with relative positionning methods: above(of relativeView:, aligned:), below(of relativeView:, aligned:)
+///
+/// - left: left aligned
+/// - center: center aligned
+/// - right: right aligned
+@objc public enum HorizontalAlign: Int {
+ case left
+ case center
+ case right
+
+ // RTL support
+ case start
+ case end
+}
+
+/// Vertical alignment used with relative positionning methods: left(of relativeView:, aligned:), right(of relativeView:, aligned:)
+///
+/// - top: top aligned
+/// - center: center aligned
+/// - bottom: bottom aligned
+@objc public enum VerticalAlign: Int {
+ case top
+ case center
+ case bottom
+}
+
+/// UIView's horizontal edges (left/right) definition
+@objc public protocol HorizontalEdge {
+}
+
+/// UIView's vertical edges (top/bottom) definition
+@objc public protocol VerticalEdge {
+}
+
+public enum FitType {
+ /**
+ **Adjust the view's height** based on the reference width.
+ * If properties related to the width have been pinned (e.g: width, left & right, margins),
+ the **reference width will be determined by these properties**, else the **current view's width**
+ will be used.
+ * The resulting width will always **match the reference width**.
+ */
+ case width
+ /**
+ **Adjust the view's width** based on the reference height.
+ * If properties related to the height have been pinned (e.g: height, top & bottom, margins),
+ the reference height will be determined by these properties, else the **current view's height**
+ will be used.
+ * The resulting height will always **match the reference height*.
+ */
+ case height
+
+ /**
+ Similar to `.width`, except that PinLayout won't constrain the resulting width to
+ match the reference width. The resulting width may be smaller of bigger depending on the view's
+ sizeThatFits(..) method result. For example a single line UILabel may returns a smaller width if its
+ string is smaller than the reference width.
+ */
+ case widthFlexible
+ /**
+ Similar to `.height`, except that PinLayout won't constrain the resulting height to
+ match the reference height. The resulting height may be smaller of bigger depending on the view's
+ sizeThatFits(..) method result.
+ */
+ case heightFlexible
+}
+
+public enum WrapType {
+ /**
+ */
+ case all
+ /**
+ */
+ case width
+ /**
+ */
+ case height
+}
+
+public struct PPadding {
+ let top: CGFloat
+ let left: CGFloat
+ let bottom: CGFloat
+ let right: CGFloat
+
+ static var zero: PPadding {
+ return PPadding(0)
+ }
+
+ init(_ all: CGFloat) {
+ top = all
+ left = all
+ bottom = all
+ right = all
+ }
+
+ init(_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) {
+ self.top = top
+ self.left = left
+ self.bottom = bottom
+ self.right = right
+ }
+
+ init(h: CGFloat, v: CGFloat) {
+ top = v
+ left = h
+ bottom = v
+ right = h
+ }
+}
+
+@objc public enum LayoutDirection: Int {
+ case auto
+ case ltr
+ case rtl
+}
+
+/// Control how PinLayout will calls `UIView.safeAreaInsetsDidChange` when the `UIView.pin.safeArea` change.
+/// This support is usefull only on iOS 8/9/10. On iOS 11 `UIView.safeAreaInsetsDidChange` is supported
+/// natively so this settings have no impact.
+@objc public enum PinSafeAreaInsetsDidChangeMode: Int {
+ /// PinLayout won't call `UIView.safeAreaInsetsDidChange` on iOS 8/9/10.
+ case disable
+ /// PinLayout will call `UIView.safeAreaInsetsDidChange` only if the UIView implement the PinSafeAreaInsetsUpdate protocol.
+ case optIn
+ /// PinLayout will automatically calls `UIView.safeAreaInsetsDidChange` if the view has implemented this method.
+ case always
+}
diff --git a/Sources/UIView+PinLayout.swift b/Sources/UIView+PinLayout.swift
index c99c394b..7ac26804 100644
--- a/Sources/UIView+PinLayout.swift
+++ b/Sources/UIView+PinLayout.swift
@@ -33,4 +33,5 @@ public extension UIView {
return PinLayoutObjCImpl(view: self, keepTransform: true)
}
}
+
#endif
diff --git a/Tests/Common/WrapContentSpec.swift b/Tests/Common/WrapContentSpec.swift
new file mode 100644
index 00000000..e877d8b1
--- /dev/null
+++ b/Tests/Common/WrapContentSpec.swift
@@ -0,0 +1,216 @@
+// Copyright (c) 2018 Luc Dion
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Quick
+import Nimble
+import PinLayout
+
+class WrapContentSpec: QuickSpec {
+ override func spec() {
+ var viewController: PViewController!
+ var rootView: BasicView!
+
+ /*
+ root
+ |
+ - aView
+ | |
+ | |- aViewChild
+ |- aViewChild2
+ |- aViewChild3
+ */
+ var aView: BasicView!
+ var aViewChild: BasicView!
+ var aViewChild2: BasicView!
+ var aViewChild3: BasicView!
+
+ beforeSuite {
+ _pinlayoutSetUnitTest(displayScale: 2)
+ }
+
+ beforeEach {
+ Pin.lastWarningText = nil
+
+ viewController = PViewController()
+ viewController.view = BasicView()
+
+ rootView = BasicView()
+ viewController.view.addSubview(rootView)
+
+ aView = BasicView()
+ aView.sizeThatFitsExpectedArea = 40 * 40
+ rootView.addSubview(aView)
+
+ aViewChild = BasicView()
+ aView.addSubview(aViewChild)
+
+ aViewChild2 = BasicView()
+ aView.addSubview(aViewChild2)
+
+ aViewChild3 = BasicView()
+ aView.addSubview(aViewChild3)
+
+ rootView.frame = CGRect(x: 0, y: 100, width: 400, height: 400)
+ }
+
+ describe("wrapContent") {
+ it("wrap and update subviews position") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
+
+ aView.pin.wrapContent()
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 260.0, height: 60.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 0.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 100.0, y: 0.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 200.0, y: 0.0, width: 60.0, height: 60.0)))
+ }
+
+ it("wrapContent(.all) should have the same result") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
+
+ aView.pin.wrapContent(.all)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 260.0, height: 60.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 0.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 100.0, y: 0.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 200.0, y: 0.0, width: 60.0, height: 60.0)))
+ }
+
+ it("wrapContent(.width) + wrapContent(.height) should have the same result") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
+
+ aView.pin.wrapContent(.width)
+ aView.pin.wrapContent(.height)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 260.0, height: 60.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 0.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 100.0, y: 0.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 200.0, y: 0.0, width: 60.0, height: 60.0)))
+ }
+
+ it("wrapContent(.all) and update subviews position") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
+
+ aView.pin.wrapContent(.all)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 260.0, height: 60.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 0.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 100.0, y: 0.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 200.0, y: 0.0, width: 60.0, height: 60.0)))
+ }
+
+ it("wrapContent(.width) and update subviews position") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
+
+ aView.pin.wrapContent(.width)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 260.0, height: 100.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 120.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 100.0, y: 120.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 200.0, y: 120.0, width: 60.0, height: 60.0)))
+ }
+ it("wrapContent(.height) and update subviews position") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
+
+ aView.pin.wrapContent(.height)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 200.0, height: 60.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 160.0, y: 0.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 260.0, y: 0.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 360.0, y: 0.0, width: 60.0, height: 60.0)))
+ }
+ it("wrap and update subviews position") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 180, y: 140, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 220, y: 180, width: 60, height: 60)
+
+ aView.pin.wrapContent()
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 120.0, height: 120.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 0.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 20.0, y: 20.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 60.0, y: 60.0, width: 60.0, height: 60.0)))
+ }
+
+ it("wrap when views are of size zero") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 0, height: 0)
+ aViewChild2.frame = CGRect(x: 180, y: 140, width: 0, height: 0)
+ aViewChild3.frame = CGRect(x: 220, y: 180, width: 0, height: 0)
+
+ aView.pin.wrapContent()
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 0.0, width: 0.0, height: 0.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 20.0, y: 20.0, width: 0.0, height: 0.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 60.0, y: 60.0, width: 0.0, height: 0.0)))
+ }
+
+ it("wrap with subviews with negative position") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: -40, y: -40, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 350, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 350, y: -100, width: 60, height: 60)
+
+ aView.pin.wrapContent()
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 450.0, height: 280.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 60.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 390.0, y: 220.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 390.0, y: 0.0, width: 60.0, height: 60.0)))
+ }
+ it("wrap and update subviews position") {
+
+ }
+ it("wrap and update subviews position") {
+ // warning
+ aView.pin.wrapContent().width(20)
+ }
+
+ it("wrap and update subviews position") {
+ // warning
+ aView.pin.width(20).wrapContent()
+ }
+
+ it("wrap and update subviews position") {
+ // warning
+ aView.pin.height(20).wrapContent()
+ }
+ }
+ }
+}
From 2de27085f715c578f131c343632cbc4ed60e0b91 Mon Sep 17 00:00:00 2001
From: Luc Dion
Date: Fri, 1 Jun 2018 18:45:19 -0400
Subject: [PATCH 008/389] Initial commit
---
.gitignore | 3 +-
README.md | 48 ++++-
Sources/Impl/PinLayoutImpl+WrapContent.swift | 37 ++--
Sources/PinLayout+Filters.swift | 28 ---
Sources/PinLayout.swift | 42 ++++-
Sources/Types+Description.swift | 4 +-
Sources/Types.swift | 45 +----
Tests/Common/WrapContentSpec.swift | 188 +++++++++++++++++--
8 files changed, 294 insertions(+), 101 deletions(-)
delete mode 100644 Sources/PinLayout+Filters.swift
diff --git a/.gitignore b/.gitignore
index 2325e32c..491ff75e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,9 +19,10 @@ TestProjects/cocoapods/macos/PinLayout-macOS.xcworkspace/
TestProjects/cocoapods/macos/Podfile.lock
TestProjects/cocoapods/tvos/PinLayout-tvOS.xcworkspace/
TestProjects/cocoapods/tvos/Podfile.lock
+
TestProjects/carthage/ios/Cartfile.resolved
TestProjects/carthage/ios/Carthage/
TestProjects/swift-package-manager
-Example/PinLayoutExampleMacOS
\ No newline at end of file
+Example/PinLayoutExampleMacOS
diff --git a/README.md b/README.md
index f4803bed..9c7fd543 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,8 @@ Extremely Fast views layouting without auto layout. No magic, pure code, full co
* Swift 3.2+ / Swift 4.0 / Objective-C
### Recent features
+* :star: Add methods `wrapConten(...)` that adjust the view's width & height to wrap all its subviews. See [wrapContent](#wrapCcontent) for more information.
+
* :star: PinLayout now support macOS. See [macOS Support](#macos_support) for more information.
* :star: PinLayout expose the `safeAreaInsets` through [`UIView.pin.safeArea`](#safeAreaInsets), this property support not only iOS 11, but is also backward compatible for earlier iOS releases (7/8/9/10). See [safeAreaInsets support](#safeAreaInsets) for more information.
@@ -61,6 +63,7 @@ Extremely Fast views layouting without auto layout. No magic, pure code, full co
* [Aspect Ratio](#aspect_ratio)
* [Margins](#margins)
* [safeAreaInsets support](#safeAreaInsets)
+ * [WrapContent](#wrapCcontent)
* [justify, align](#justify_align)
* [UIView's transforms](#uiview_transform)
* [Warnings](#warnings)
@@ -1134,8 +1137,51 @@ This example runs perfectly on a iPhone X (iOS 11), but it also runs on any devi
+
+## WrapContent
-
+The following methods are useful to adjust the view's width and/or height to wrap all its subviews. These method also adjust subviews position to create a tight wrap.
+
+**Methods:**
+
+* **`wrapContent()`**
+Bla.
+* **`wrapContent(padding: CGFloat)`**
+Bla.
+* **`wrapContent(padding: UIEdgeInsets)`**
+Bla.
+* **`wrapContent(:WrapType)`**
+Bla.
+* **`wrapContent(:WrapType, padding: CGFloat)`**
+Bla.
+* **`wrapContent(:WrapType, padding: UIEdgeInsets)`**
+Bla.
+
+TABLE SHOWING DIFFERENCES!!!
+
+###### Usage examples:
+```swift
+ view.pin.wrapContent().center() // wrap all subviews and centered the view inside its parent.
+ view.pin.wrapContent(padding: 20) // wrap all subviews with a padding of 20 pixels all around
+```
+
+
+###### Example:
+...:
+
+
+
+
+```swift
+ viewA.pin.....
+```
+
+
+
+
+
+
+
## justify() / align()
**Methods:**
diff --git a/Sources/Impl/PinLayoutImpl+WrapContent.swift b/Sources/Impl/PinLayoutImpl+WrapContent.swift
index 06d2a928..d89e07f7 100644
--- a/Sources/Impl/PinLayoutImpl+WrapContent.swift
+++ b/Sources/Impl/PinLayoutImpl+WrapContent.swift
@@ -28,12 +28,27 @@ extension PinLayoutImpl {
return wrapContent(.all, padding: .zero, { return "wrapContent()" })
}
+ func wrapContent(padding: CGFloat) -> PinLayout {
+ return wrapContent(.all, padding: UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), { return "wrapContent(padding: \(padding)" })
+ }
+
+ func wrapContent(padding: UIEdgeInsets) -> PinLayout {
+ return wrapContent(.all, padding: padding, { return "wrapContent(padding: \(insetsDescription(padding))" })
+ }
+
func wrapContent(_ type: WrapType) -> PinLayout {
return wrapContent(type, padding: .zero, { return "wrapContent(\(type.description)" })
}
- @discardableResult
- private func wrapContent(_ type: WrapType, padding: PPadding, _ context: Context) -> PinLayout {
+ func wrapContent(_ type: WrapType, padding: CGFloat) -> PinLayout {
+ return wrapContent(type, padding: UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), { return "wrapContent(\(type.description), padding: \(padding)" })
+ }
+
+ func wrapContent(_ type: WrapType, padding: UIEdgeInsets) -> PinLayout {
+ return wrapContent(type, padding: padding, { return "wrapContent(\(type.description), padding: \(insetsDescription(padding))" })
+ }
+
+ private func wrapContent(_ type: WrapType, padding: UIEdgeInsets, _ context: Context) -> PinLayout {
let subviews = view.subviews
guard !subviews.isEmpty else { return self }
let firstViewFrame = subviews[0].frame
@@ -61,28 +76,22 @@ extension PinLayoutImpl {
var offsetDx: CGFloat = 0
var offsetDy: CGFloat = 0
- if type == .all || type == .width {
- let contentWidth = maxX - minX
+ if type == .all || type == .horizontally {
+ let contentWidth = maxX - minX + padding.left + padding.right
if contentWidth >= 0 {
setWidth(contentWidth, context)
}
- offsetDx = -minX
-// let contentWidth = view.subviews.max(by: { subview1, subview2 in
-// subview1.frame.maxX < subview2.frame.maxX
-// })?.frame.maxX ?? 0
+ offsetDx = -minX + padding.left
}
- if type == .all || type == .height {
- let contentHeight = maxY - minY
+ if type == .all || type == .vertically {
+ let contentHeight = maxY - minY + padding.top + padding.bottom
if contentHeight >= 0 {
setHeight(contentHeight, context)
}
- offsetDy = -minY
-// let contentHeight = view.subviews.max(by: { subview1, subview2 in
-// subview1.frame.maxY < subview2.frame.maxY
-// })?.frame.maxY ?? 0
+ offsetDy = -minY + padding.top
}
if offsetDx != 0 || offsetDy != 0 {
diff --git a/Sources/PinLayout+Filters.swift b/Sources/PinLayout+Filters.swift
deleted file mode 100644
index 400ca72e..00000000
--- a/Sources/PinLayout+Filters.swift
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2017 Luc Dion
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#if os(iOS) || os(tvOS)
-import UIKit
-
-// Filter out all hidden views (isHidden is true or alpha is 0)
-public func visible(_ views: [UIView]) -> [UIView] {
- return views.filter({ !$0.isHidden && $0.alpha > 0 })
-}
-
-#endif
diff --git a/Sources/PinLayout.swift b/Sources/PinLayout.swift
index 9a659ad9..543f2e85 100644
--- a/Sources/PinLayout.swift
+++ b/Sources/PinLayout.swift
@@ -308,10 +308,48 @@ public protocol PinLayout {
@discardableResult func size(of view: NSView) -> PinLayout
#endif
+ /**
+ Adjust the view's width & height to wrap all its subviews. The method also adjust subviews position to create a tight wrap.
+ */
@discardableResult func wrapContent() -> PinLayout
+ /**
+ Adjust the view's width & height to wrap all its subviews. The method also adds a padding around all subviews.
+
+ - Parameters:
+ - padding: Specify a padding value.
+ */
+ @discardableResult func wrapContent(padding: CGFloat) -> PinLayout
+ /**
+ Adjust the view's width & height to wrap all its subviews. The method also adds a padding around all subviews.
+
+ - Parameters:
+ - padding: Specify a padding using an UIEdgeInsets.
+ */
+ @discardableResult func wrapContent(padding: UIEdgeInsets) -> PinLayout
+
+ /**
+ Adjust the view's width AND/OR height to wrap all its subviews.
+
+ - Parameters:
+ - type: Specify the wrap type (.all, .horizontally, .vertically)
+ */
@discardableResult func wrapContent(_ type: WrapType) -> PinLayout
- @discardableResult func wrapContent(padding: PPadding) -> PinLayout
- @discardableResult func wrapContent(_ type: WrapType, padding: PPadding) -> PinLayout
+ /**
+ Adjust the view's width AND/OR height to wrap all its subviews. The method also adds a padding around all subviews.
+
+ - Parameters:
+ - type: Specify the wrap type (.all, .horizontally, .vertically)
+ - padding: Specify a padding value.
+ */
+ @discardableResult func wrapContent(_ type: WrapType, padding: CGFloat) -> PinLayout
+ /**
+ Adjust the view's width AND/OR height to wrap all its subviews. The method also adds a padding around all subviews.
+
+ - Parameters:
+ - type: Specify the wrap type (.all, .horizontally, .vertically)
+ - padding: Specify a padding using an UIEdgeInsets.
+ */
+ @discardableResult func wrapContent(_ type: WrapType, padding: UIEdgeInsets) -> PinLayout
/**
Set the view aspect ratio.
diff --git a/Sources/Types+Description.swift b/Sources/Types+Description.swift
index 28946b2a..ccfad56f 100644
--- a/Sources/Types+Description.swift
+++ b/Sources/Types+Description.swift
@@ -55,8 +55,8 @@ extension WrapType {
var description: String {
switch self {
case .all: return ".all"
- case .width: return ".width"
- case .height: return ".height"
+ case .horizontally: return ".horizontally"
+ case .vertically: return ".vertically"
}
}
}
diff --git a/Sources/Types.swift b/Sources/Types.swift
index 32f691c3..77cce2b0 100644
--- a/Sources/Types.swift
+++ b/Sources/Types.swift
@@ -167,47 +167,12 @@ public enum FitType {
}
public enum WrapType {
- /**
- */
+ /// Adjust the view's width AND height to wrap all its subviews.
case all
- /**
- */
- case width
- /**
- */
- case height
-}
-
-public struct PPadding {
- let top: CGFloat
- let left: CGFloat
- let bottom: CGFloat
- let right: CGFloat
-
- static var zero: PPadding {
- return PPadding(0)
- }
-
- init(_ all: CGFloat) {
- top = all
- left = all
- bottom = all
- right = all
- }
-
- init(_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) {
- self.top = top
- self.left = left
- self.bottom = bottom
- self.right = right
- }
-
- init(h: CGFloat, v: CGFloat) {
- top = v
- left = h
- bottom = v
- right = h
- }
+ /// Adjust only the view's width to wrap all its subviews. The view's height won't be modified.
+ case horizontally
+ /// Adjust only the view's height to wrap all its subviews. The view's width won't be modified.
+ case vertically
}
@objc public enum LayoutDirection: Int {
diff --git a/Tests/Common/WrapContentSpec.swift b/Tests/Common/WrapContentSpec.swift
index e877d8b1..eaaa684c 100644
--- a/Tests/Common/WrapContentSpec.swift
+++ b/Tests/Common/WrapContentSpec.swift
@@ -104,8 +104,8 @@ class WrapContentSpec: QuickSpec {
aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
- aView.pin.wrapContent(.width)
- aView.pin.wrapContent(.height)
+ aView.pin.wrapContent(.horizontally)
+ aView.pin.wrapContent(.vertically)
expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 260.0, height: 60.0)))
expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 0.0, width: 100.0, height: 40.0)))
@@ -133,7 +133,7 @@ class WrapContentSpec: QuickSpec {
aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
- aView.pin.wrapContent(.width)
+ aView.pin.wrapContent(.horizontally)
expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 260.0, height: 100.0)))
expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 120.0, width: 100.0, height: 40.0)))
@@ -146,7 +146,7 @@ class WrapContentSpec: QuickSpec {
aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
- aView.pin.wrapContent(.height)
+ aView.pin.wrapContent(.vertically)
expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 200.0, height: 60.0)))
expect(aViewChild.frame).to(equal(CGRect(x: 160.0, y: 0.0, width: 100.0, height: 40.0)))
@@ -194,22 +194,184 @@ class WrapContentSpec: QuickSpec {
expect(aViewChild2.frame).to(equal(CGRect(x: 390.0, y: 220.0, width: 60.0, height: 60.0)))
expect(aViewChild3.frame).to(equal(CGRect(x: 390.0, y: 0.0, width: 60.0, height: 60.0)))
}
+ }
+
+ describe("wrapContent with padding") {
it("wrap and update subviews position") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
+
+ aView.pin.wrapContent(padding: 10)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 280.0, height: 80.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 10.0, y: 10.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 110.0, y: 10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 210.0, y: 10.0, width: 60.0, height: 60.0)))
}
- it("wrap and update subviews position") {
- // warning
- aView.pin.wrapContent().width(20)
+ it("wrap and update subviews position + center") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
+
+ aView.pin.wrapContent(padding: 10).center()
+
+ expect(aView.frame).to(equal(CGRect(x: 60.0, y: 160.0, width: 280.0, height: 80.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 10.0, y: 10.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 110.0, y: 10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 210.0, y: 10.0, width: 60.0, height: 60.0)))
}
- it("wrap and update subviews position") {
- // warning
- aView.pin.width(20).wrapContent()
+ it("wrap horizontally + padding") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 120, width: 60, height: 60)
+
+ aView.pin.wrapContent(.horizontally, padding: 10)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 280.0, height: 100.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 10.0, y: 120.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 110.0, y: 120.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 210.0, y: 120.0, width: 60.0, height: 60.0)))
}
- it("wrap and update subviews position") {
- // warning
- aView.pin.height(20).wrapContent()
+ it("wrap vertically + padding") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
+
+ aView.pin.wrapContent(.vertically, padding: 10)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 200.0, height: 100.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 160.0, y: 10.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 260.0, y: 10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 360.0, y: 30.0, width: 60.0, height: 60.0)))
+ }
+
+ it("wrap horizontally + negative padding") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 160, width: 60, height: 60)
+ aView.pin.wrapContent(.horizontally, padding: -10)
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 240.0, height: 100.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: -10.0, y: 120.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 90.0, y: 120.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 190.0, y: 160.0, width: 60.0, height: 60.0)))
+ }
+
+ it("wrap vertically + negative padding") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 160, width: 60, height: 60)
+
+ aView.pin.wrapContent(.vertically, padding: -10)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 200.0, height: 80.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 160.0, y: -10.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 260.0, y: -10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 360.0, y: 30.0, width: 60.0, height: 60.0)))
+ }
+
+
+ it("wrap all + padding UIEdgeInsets") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
+ aView.pin.wrapContent(padding: UIEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 320.0, height: 120.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 120.0, y: 10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 220.0, y: 30.0, width: 60.0, height: 60.0)))
+ }
+
+ it("wrap all + padding UIEdgeInsets") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
+ aView.pin.wrapContent(.all, padding: UIEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 320.0, height: 120.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 120.0, y: 10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 220.0, y: 30.0, width: 60.0, height: 60.0)))
+
+ }
+
+ it("wrap horizontally + padding UIEdgeInsets") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
+ aView.pin.wrapContent(.horizontally, padding: UIEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 320.0, height: 100.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 20.0, y: 120.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 120.0, y: 120.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 220.0, y: 140.0, width: 60.0, height: 60.0)))
+
+ }
+
+
+ it("wrap vertically + padding UIEdgeInsets") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
+ aView.pin.wrapContent(.vertically, padding: UIEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 200.0, height: 120.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 160.0, y: 10.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 260.0, y: 10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 360.0, y: 30.0, width: 60.0, height: 60.0)))
+
+ }
+
+ it("wrap all + negative padding UIEdgeInsets") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
+ aView.pin.wrapContent(.all, padding: UIEdgeInsets(top: -10, left: -20, bottom: -30, right: -40))
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 200.0, height: 40.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: -20.0, y: -10.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 80.0, y: -10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 180.0, y: 10.0, width: 60.0, height: 60.0)))
+ }
+ }
+
+ describe("wrapContent + min/max") {
+ it("wrap all + maxWidth + maxHeight") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 130, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
+
+ aView.pin.wrapContent().maxWidth(200).maxHeight(50)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 200.0, height: 50.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 0.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 100.0, y: 10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 200.0, y: 20.0, width: 60.0, height: 60.0)))
+ }
+
+ it("wrap all + minWidth + minHeight") {
+ aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
+ aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
+ aViewChild2.frame = CGRect(x: 260, y: 130, width: 60, height: 60)
+ aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
+
+ aView.pin.wrapContent().minWidth(300).minHeight(100)
+
+ expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 300.0, height: 100.0)))
+ expect(aViewChild.frame).to(equal(CGRect(x: 0.0, y: 0.0, width: 100.0, height: 40.0)))
+ expect(aViewChild2.frame).to(equal(CGRect(x: 100.0, y: 10.0, width: 60.0, height: 60.0)))
+ expect(aViewChild3.frame).to(equal(CGRect(x: 200.0, y: 20.0, width: 60.0, height: 60.0)))
}
}
}
From 7b39081d5fe1da00f3a7ecbd3143abaae4545750 Mon Sep 17 00:00:00 2001
From: Luc Dion
Date: Sat, 2 Jun 2018 07:11:58 -0400
Subject: [PATCH 009/389] Update for tvOS and macOS
---
.../xcschemes/PinLayoutSample.xcscheme | 2 +-
PinLayout.xcodeproj/project.pbxproj | 22 ++++++++++++++-----
.../xcschemes/PinLayout-iOS.xcscheme | 2 +-
.../xcschemes/PinLayout-macOS.xcscheme | 2 +-
.../xcschemes/PinLayout-tvOS.xcscheme | 2 +-
Sources/Impl/PinLayoutImpl+WrapContent.swift | 16 +++++++-------
Sources/PinLayout.swift | 9 ++++++++
Sources/Types+Description.swift | 6 ++++-
Tests/Common/WrapContentSpec.swift | 17 +++++++-------
9 files changed, 51 insertions(+), 27 deletions(-)
diff --git a/Example/PinLayoutSample.xcodeproj/xcshareddata/xcschemes/PinLayoutSample.xcscheme b/Example/PinLayoutSample.xcodeproj/xcshareddata/xcschemes/PinLayoutSample.xcscheme
index d6642870..06ff0930 100644
--- a/Example/PinLayoutSample.xcodeproj/xcshareddata/xcschemes/PinLayoutSample.xcscheme
+++ b/Example/PinLayoutSample.xcodeproj/xcshareddata/xcschemes/PinLayoutSample.xcscheme
@@ -1,6 +1,6 @@
PinLayout {
- return wrapContent(.all, padding: .zero, { return "wrapContent()" })
+ return wrapContent(.all, padding: PEdgeInsets(top: 0, left: 0, bottom: 0, right: 0), { return "wrapContent()" })
}
func wrapContent(padding: CGFloat) -> PinLayout {
- return wrapContent(.all, padding: UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), { return "wrapContent(padding: \(padding)" })
+ return wrapContent(.all, padding: PEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), { return "wrapContent(padding: \(padding)" })
}
- func wrapContent(padding: UIEdgeInsets) -> PinLayout {
+ func wrapContent(padding: PEdgeInsets) -> PinLayout {
return wrapContent(.all, padding: padding, { return "wrapContent(padding: \(insetsDescription(padding))" })
}
func wrapContent(_ type: WrapType) -> PinLayout {
- return wrapContent(type, padding: .zero, { return "wrapContent(\(type.description)" })
+ return wrapContent(type, padding: PEdgeInsets(top: 0, left: 0, bottom: 0, right: 0), { return "wrapContent(\(type.description)" })
}
func wrapContent(_ type: WrapType, padding: CGFloat) -> PinLayout {
- return wrapContent(type, padding: UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), { return "wrapContent(\(type.description), padding: \(padding)" })
+ return wrapContent(type, padding: PEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), { return "wrapContent(\(type.description), padding: \(padding)" })
}
- func wrapContent(_ type: WrapType, padding: UIEdgeInsets) -> PinLayout {
+ func wrapContent(_ type: WrapType, padding: PEdgeInsets) -> PinLayout {
return wrapContent(type, padding: padding, { return "wrapContent(\(type.description), padding: \(insetsDescription(padding))" })
}
- private func wrapContent(_ type: WrapType, padding: UIEdgeInsets, _ context: Context) -> PinLayout {
+ private func wrapContent(_ type: WrapType, padding: PEdgeInsets, _ context: Context) -> PinLayout {
let subviews = view.subviews
guard !subviews.isEmpty else { return self }
let firstViewFrame = subviews[0].frame
@@ -57,7 +57,7 @@ extension PinLayoutImpl {
var minY = firstViewFrame.minY
var maxY = firstViewFrame.maxY
- for var i in 1.. PinLayout
+ #elseif os(macOS)
+ @discardableResult func wrapContent(padding: NSEdgeInsets) -> PinLayout
+ #endif
/**
Adjust the view's width AND/OR height to wrap all its subviews.
@@ -349,7 +353,12 @@ public protocol PinLayout {
- type: Specify the wrap type (.all, .horizontally, .vertically)
- padding: Specify a padding using an UIEdgeInsets.
*/
+ #if os(iOS) || os(tvOS)
@discardableResult func wrapContent(_ type: WrapType, padding: UIEdgeInsets) -> PinLayout
+ #elseif os(macOS)
+ @discardableResult func wrapContent(_ type: WrapType, padding: NSEdgeInsets) -> PinLayout
+ #endif
+
/**
Set the view aspect ratio.
diff --git a/Sources/Types+Description.swift b/Sources/Types+Description.swift
index ccfad56f..8a0a7dd7 100644
--- a/Sources/Types+Description.swift
+++ b/Sources/Types+Description.swift
@@ -6,7 +6,11 @@
// Copyright Š 2018 mcswiftlayyout.mirego.com. All rights reserved.
//
-import Foundation
+#if os(iOS) || os(tvOS)
+import UIKit
+#else
+import AppKit
+#endif
extension HorizontalAlign {
var description: String {
diff --git a/Tests/Common/WrapContentSpec.swift b/Tests/Common/WrapContentSpec.swift
index eaaa684c..ff56ae01 100644
--- a/Tests/Common/WrapContentSpec.swift
+++ b/Tests/Common/WrapContentSpec.swift
@@ -279,13 +279,12 @@ class WrapContentSpec: QuickSpec {
expect(aViewChild3.frame).to(equal(CGRect(x: 360.0, y: 30.0, width: 60.0, height: 60.0)))
}
-
it("wrap all + padding UIEdgeInsets") {
aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
- aView.pin.wrapContent(padding: UIEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
+ aView.pin.wrapContent(padding: PEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 320.0, height: 120.0)))
expect(aViewChild.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 100.0, height: 40.0)))
expect(aViewChild2.frame).to(equal(CGRect(x: 120.0, y: 10.0, width: 60.0, height: 60.0)))
@@ -297,7 +296,7 @@ class WrapContentSpec: QuickSpec {
aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
- aView.pin.wrapContent(.all, padding: UIEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
+ aView.pin.wrapContent(.all, padding: PEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 320.0, height: 120.0)))
expect(aViewChild.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 100.0, height: 40.0)))
expect(aViewChild2.frame).to(equal(CGRect(x: 120.0, y: 10.0, width: 60.0, height: 60.0)))
@@ -305,12 +304,12 @@ class WrapContentSpec: QuickSpec {
}
- it("wrap horizontally + padding UIEdgeInsets") {
+ it("wrap horizontally + padding PEdgeInsets") {
aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
- aView.pin.wrapContent(.horizontally, padding: UIEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
+ aView.pin.wrapContent(.horizontally, padding: PEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 320.0, height: 100.0)))
expect(aViewChild.frame).to(equal(CGRect(x: 20.0, y: 120.0, width: 100.0, height: 40.0)))
expect(aViewChild2.frame).to(equal(CGRect(x: 120.0, y: 120.0, width: 60.0, height: 60.0)))
@@ -319,12 +318,12 @@ class WrapContentSpec: QuickSpec {
}
- it("wrap vertically + padding UIEdgeInsets") {
+ it("wrap vertically + padding PEdgeInsets") {
aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
- aView.pin.wrapContent(.vertically, padding: UIEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
+ aView.pin.wrapContent(.vertically, padding: PEdgeInsets(top: 10, left: 20, bottom: 30, right: 40))
expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 200.0, height: 120.0)))
expect(aViewChild.frame).to(equal(CGRect(x: 160.0, y: 10.0, width: 100.0, height: 40.0)))
expect(aViewChild2.frame).to(equal(CGRect(x: 260.0, y: 10.0, width: 60.0, height: 60.0)))
@@ -332,12 +331,12 @@ class WrapContentSpec: QuickSpec {
}
- it("wrap all + negative padding UIEdgeInsets") {
+ it("wrap all + negative padding PEdgeInsets") {
aView.frame = CGRect(x: 20, y: 10, width: 200, height: 100)
aViewChild.frame = CGRect(x: 160, y: 120, width: 100, height: 40)
aViewChild2.frame = CGRect(x: 260, y: 120, width: 60, height: 60)
aViewChild3.frame = CGRect(x: 360, y: 140, width: 60, height: 60)
- aView.pin.wrapContent(.all, padding: UIEdgeInsets(top: -10, left: -20, bottom: -30, right: -40))
+ aView.pin.wrapContent(.all, padding: PEdgeInsets(top: -10, left: -20, bottom: -30, right: -40))
expect(aView.frame).to(equal(CGRect(x: 20.0, y: 10.0, width: 200.0, height: 40.0)))
expect(aViewChild.frame).to(equal(CGRect(x: -20.0, y: -10.0, width: 100.0, height: 40.0)))
expect(aViewChild2.frame).to(equal(CGRect(x: 80.0, y: -10.0, width: 60.0, height: 60.0)))
From 174137d2569310a60b4b676b0647cd1e70f11024 Mon Sep 17 00:00:00 2001
From: Luc Dion
Date: Mon, 4 Jun 2018 22:28:50 -0400
Subject: [PATCH 010/389] Add wrapContent documentation.
---
README.md | 49 +++++++++++++----------
docs/images/wrapContent_all.png | Bin 0 -> 25924 bytes
docs/images/wrapContent_before.png | Bin 0 -> 25602 bytes
docs/images/wrapContent_example_1.png | Bin 0 -> 60959 bytes
docs/images/wrapContent_horizontally.png | Bin 0 -> 26242 bytes
docs/images/wrapContent_padding.png | Bin 0 -> 25830 bytes
docs/images/wrapContent_vertically.png | Bin 0 -> 25552 bytes
7 files changed, 28 insertions(+), 21 deletions(-)
create mode 100644 docs/images/wrapContent_all.png
create mode 100644 docs/images/wrapContent_before.png
create mode 100644 docs/images/wrapContent_example_1.png
create mode 100644 docs/images/wrapContent_horizontally.png
create mode 100644 docs/images/wrapContent_padding.png
create mode 100644 docs/images/wrapContent_vertically.png
diff --git a/README.md b/README.md
index 9c7fd543..a134fc6c 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ Extremely Fast views layouting without auto layout. No magic, pure code, full co
* Swift 3.2+ / Swift 4.0 / Objective-C
### Recent features
-* :star: Add methods `wrapConten(...)` that adjust the view's width & height to wrap all its subviews. See [wrapContent](#wrapCcontent) for more information.
+* :star: Add `wrapContent()` methods that adjust view's width & height to wrap all its subviews. See [wrapContent](#wrapContent) for more information.
* :star: PinLayout now support macOS. See [macOS Support](#macos_support) for more information.
@@ -1137,50 +1137,57 @@ This example runs perfectly on a iPhone X (iOS 11), but it also runs on any devi
-
+
## WrapContent
-The following methods are useful to adjust the view's width and/or height to wrap all its subviews. These method also adjust subviews position to create a tight wrap.
+The following methods are useful to adjust view's width and/or height to wrap all its subviews. These methods also adjust subviews position to create a tight wrap.
**Methods:**
* **`wrapContent()`**
-Bla.
-* **`wrapContent(padding: CGFloat)`**
-Bla.
-* **`wrapContent(padding: UIEdgeInsets)`**
-Bla.
+**`wrapContent(padding: CGFloat)`**
+**`wrapContent(padding: UIEdgeInsets)`**
+Adjust the view's width and height to wrap all its subviews. The method also adjusts subviews position to create a tight wrap. It is also possible to specify an optional padding around all subviews.
* **`wrapContent(:WrapType)`**
-Bla.
-* **`wrapContent(:WrapType, padding: CGFloat)`**
-Bla.
-* **`wrapContent(:WrapType, padding: UIEdgeInsets)`**
-Bla.
-
-TABLE SHOWING DIFFERENCES!!!
+**`wrapContent(:WrapType, padding: CGFloat)`** **`wrapContent(:WrapType, padding: UIEdgeInsets)`**
+Adjust the view's width AND/OR height to wrap all its subviews. WrapType values are `.horizontally`/`.vertically`/`.all` It is also possible to specify an optional padding around all subviews.
###### Usage examples:
```swift
view.pin.wrapContent().center() // wrap all subviews and centered the view inside its parent.
view.pin.wrapContent(padding: 20) // wrap all subviews with a padding of 20 pixels all around
+ view.pin.wrapContent(.horizontally)
```
-
###### Example:
-...:
+This example show the result of different `wrapContent()` method calls.
+Here is the initial state:
-
+
+| Source code | Result | Description |
+|---------------------|----------|-------------------|
+| `view.pin.wrapContent()` |
| Adjust the view's height and width to tight fit its subviews. |
+| `view.pin.wrapContent(padding: 10)` |
| Adjust the view's height and width and add a padding of 10 pixels around its subviews. |
+| `view.pin.wrapContent(.horizontally)` |
| Adjust only the view's width. |
+| `view.pin.wrapContent(.vertically)` |
| Adjust only the view's height. |
+
+
+###### Example:
+This example shows how a view (`containerView`) with two subviews (`imageView` and `label`), can be adjusted to the size of its subviews and then centered inside its parent.
+
+
```swift
- viewA.pin.....
+ label.pin.below(of: imageView, aligned: .center).marginTop(4)
+ containerView.pin.wrapContent().center()
```
+* Line 1: Position the label below the imageView aligned on its center with a top margin of 4 pixels.
+* Line 2: Adjust the `containerView`'s size and position its subviews to create a tight wrap around them, and then it center the `containerView` inside its parent (superview).
-
-
## justify() / align()
diff --git a/docs/images/wrapContent_all.png b/docs/images/wrapContent_all.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f00ca0f08a6ad8bd097828e69b1252e4c901d57
GIT binary patch
literal 25924
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
literal 0
HcmV?d00001
diff --git a/docs/images/wrapContent_before.png b/docs/images/wrapContent_before.png
new file mode 100644
index 0000000000000000000000000000000000000000..ad081829f7d61ddffbf6f33896f78a802ffc0e90
GIT binary patch
literal 25602
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
YDgT+?-JJ&f@4CuYugmAi-n{#N0G`TvF#rGn
literal 0
HcmV?d00001
diff --git a/docs/images/wrapContent_example_1.png b/docs/images/wrapContent_example_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..38ca574f4b5225b47726a16b01e3d71225637a91
GIT binary patch
literal 60959
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