From 06a91e4517dcca08991a418fdaef6eb5aae274c4 Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Mon, 11 Jun 2018 08:12:48 -0400 Subject: [PATCH 01/11] Make PinLayout implementation public and remove interface --- Sources/Impl/PinLayoutImpl+Coordinates.swift | 2 +- Sources/Impl/PinLayoutImpl+Layouting.swift | 2 +- Sources/Impl/PinLayoutImpl+Relative.swift | 52 ++-- Sources/Impl/PinLayoutImpl+Size.swift | 22 +- Sources/Impl/PinLayoutImpl+Warning.swift | 2 +- Sources/Impl/PinLayoutImpl+WrapContent.swift | 14 +- Sources/Impl/PinLayoutImpl.swift | 258 +++++++++---------- Sources/NSView+PinLayout.swift | 4 +- Sources/ObjectiveC/PinLayoutObjCImpl.swift | 4 +- Sources/PinLayout.swift | 3 +- Sources/UIView+PinLayout.swift | 4 +- 11 files changed, 184 insertions(+), 183 deletions(-) diff --git a/Sources/Impl/PinLayoutImpl+Coordinates.swift b/Sources/Impl/PinLayoutImpl+Coordinates.swift index 4cfb8738..00edf3dd 100644 --- a/Sources/Impl/PinLayoutImpl+Coordinates.swift +++ b/Sources/Impl/PinLayoutImpl+Coordinates.swift @@ -23,7 +23,7 @@ import AppKit #endif -extension PinLayoutImpl { +extension PinLayout { internal func top(_ context: Context) { setTop(0, context) } diff --git a/Sources/Impl/PinLayoutImpl+Layouting.swift b/Sources/Impl/PinLayoutImpl+Layouting.swift index b08499a1..769fe61c 100644 --- a/Sources/Impl/PinLayoutImpl+Layouting.swift +++ b/Sources/Impl/PinLayoutImpl+Layouting.swift @@ -24,7 +24,7 @@ #endif // MARK: UIView's frame computation methods -extension PinLayoutImpl { +extension PinLayout { public func layout() { apply() } diff --git a/Sources/Impl/PinLayoutImpl+Relative.swift b/Sources/Impl/PinLayoutImpl+Relative.swift index f30d9852..d1fc19fb 100644 --- a/Sources/Impl/PinLayoutImpl+Relative.swift +++ b/Sources/Impl/PinLayoutImpl+Relative.swift @@ -23,27 +23,27 @@ import AppKit #endif -extension PinLayoutImpl { +extension PinLayout { // // above(of ...) // - func above(of relativeView: PView) -> PinLayout { + public func above(of relativeView: PView) -> PinLayout { func context() -> String { return "above(of: \(relativeView))" } return above(relativeViews: [relativeView], aligned: nil, context: context) } - func above(of relativeViews: [PView]) -> PinLayout { + public func above(of relativeViews: [PView]) -> PinLayout { func context() -> String { return "above(of: \(relativeViews))" } return above(relativeViews: relativeViews, aligned: nil, context: context) } - func above(of relativeView: PView, aligned: HorizontalAlign) -> PinLayout { + public 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) } - func above(of relativeViews: [PView], aligned: HorizontalAlign) -> PinLayout { + public 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) } @@ -51,22 +51,22 @@ extension PinLayoutImpl { // // below(of ...) // - func below(of relativeView: PView) -> PinLayout { + public func below(of relativeView: PView) -> PinLayout { func context() -> String { return "below(of: \(relativeView))" } return below(relativeViews: [relativeView], aligned: nil, context: context) } - func below(of relativeViews: [PView]) -> PinLayout { + public func below(of relativeViews: [PView]) -> PinLayout { func context() -> String { return "below(of: \(relativeViews))" } return below(relativeViews: relativeViews, aligned: nil, context: context) } - func below(of relativeView: PView, aligned: HorizontalAlign) -> PinLayout { + public 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) } - func below(of relativeViews: [PView], aligned: HorizontalAlign) -> PinLayout { + public 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) } @@ -74,22 +74,22 @@ extension PinLayoutImpl { // // left(of ...) // - func left(of relativeView: PView) -> PinLayout { + public func left(of relativeView: PView) -> PinLayout { func context() -> String { return "left(of: \(relativeView))" } return left(relativeViews: [relativeView], aligned: nil, context: context) } - func left(of relativeViews: [PView]) -> PinLayout { + public func left(of relativeViews: [PView]) -> PinLayout { func context() -> String { return "left(of: \(relativeViews))" } return left(relativeViews: relativeViews, aligned: nil, context: context) } - func left(of relativeView: PView, aligned: VerticalAlign) -> PinLayout { + public 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) } - func left(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout { + public 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) } @@ -97,27 +97,27 @@ extension PinLayoutImpl { // // right(of ...) // - func right(of relativeView: PView) -> PinLayout { + public func right(of relativeView: PView) -> PinLayout { func context() -> String { return "right(of: \(relativeView))" } return right(relativeViews: [relativeView], aligned: nil, context: context) } - func right(of relativeViews: [PView]) -> PinLayout { + public func right(of relativeViews: [PView]) -> PinLayout { func context() -> String { return "right(of: \(relativeViews))" } return right(relativeViews: relativeViews, aligned: nil, context: context) } - func right(of relativeView: PView, aligned: VerticalAlign) -> PinLayout { + public 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) } - func right(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout { + public 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) } - func before(of relativeView: PView) -> PinLayout { + public func before(of relativeView: PView) -> PinLayout { func context() -> String { return "before(of: \(relativeView))" } if isLTR() { return left(relativeViews: [relativeView], aligned: nil, context: context) @@ -126,7 +126,7 @@ extension PinLayoutImpl { } } - func before(of relativeViews: [PView]) -> PinLayout { + public func before(of relativeViews: [PView]) -> PinLayout { func context() -> String { return "before(of: \(relativeViews))" } if isLTR() { return left(relativeViews: relativeViews, aligned: nil, context: context) @@ -135,7 +135,7 @@ extension PinLayoutImpl { } } - func before(of relativeView: PView, aligned: VerticalAlign) -> PinLayout { + public func before(of relativeView: PView, aligned: VerticalAlign) -> PinLayout { func context() -> String { return "before(of: \(relativeView), aligned: \(aligned))" } if isLTR() { return left(relativeViews: [relativeView], aligned: aligned, context: context) @@ -144,7 +144,7 @@ extension PinLayoutImpl { } } - func before(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout { + public func before(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout { func context() -> String { return "before(of: \(relativeViews), aligned: \(aligned))" } if isLTR() { return left(relativeViews: relativeViews, aligned: aligned, context: context) @@ -153,7 +153,7 @@ extension PinLayoutImpl { } } - func after(of relativeView: PView) -> PinLayout { + public func after(of relativeView: PView) -> PinLayout { func context() -> String { return "after(of: \(relativeView))" } if isLTR() { return right(relativeViews: [relativeView], aligned: nil, context: context) @@ -162,7 +162,7 @@ extension PinLayoutImpl { } } - func after(of relativeViews: [PView]) -> PinLayout { + public func after(of relativeViews: [PView]) -> PinLayout { func context() -> String { return "after(of: \(relativeViews))" } if isLTR() { return right(relativeViews: relativeViews, aligned: nil, context: context) @@ -171,7 +171,7 @@ extension PinLayoutImpl { } } - func after(of relativeView: PView, aligned: VerticalAlign) -> PinLayout { + public func after(of relativeView: PView, aligned: VerticalAlign) -> PinLayout { func context() -> String { return "after(of: \(relativeView))" } if isLTR() { return right(relativeViews: [relativeView], aligned: aligned, context: context) @@ -180,7 +180,7 @@ extension PinLayoutImpl { } } - func after(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout { + public func after(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout { func context() -> String { return "after(of: \(relativeViews), aligned: \(aligned))" } if isLTR() { return right(relativeViews: relativeViews, aligned: aligned, context: context) @@ -191,7 +191,7 @@ extension PinLayoutImpl { } // MARK: fileprivate -extension PinLayoutImpl { +extension PinLayout { fileprivate func above(relativeViews: [PView], aligned: HorizontalAlign?, context: Context) -> PinLayout { guard let relativeViews = validateRelativeViews(relativeViews, context: context) else { return self } diff --git a/Sources/Impl/PinLayoutImpl+Size.swift b/Sources/Impl/PinLayoutImpl+Size.swift index bb91bccf..94b83e6a 100644 --- a/Sources/Impl/PinLayoutImpl+Size.swift +++ b/Sources/Impl/PinLayoutImpl+Size.swift @@ -64,39 +64,39 @@ extension FitType { } } -extension PinLayoutImpl { - func size(_ size: CGSize) -> PinLayout { +extension PinLayout { + public func size(_ size: CGSize) -> PinLayout { return setSize(size, { return "size(CGSize(width: \(size.width), height: \(size.height)))" }) } - func size(_ sideLength: CGFloat) -> PinLayout { + public func size(_ sideLength: CGFloat) -> PinLayout { return setSize(CGSize(width: sideLength, height: sideLength), { return "size(sideLength: \(sideLength))" }) } - func size(_ percent: Percent) -> PinLayout { + public 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) } - func size(of view: PView) -> PinLayout { + public func size(of view: PView) -> PinLayout { func context() -> String { return "size(of \(viewDescription(view)))" } return setSize(view.getRect(keepTransform: keepTransform).size, context) } @discardableResult - func aspectRatio(_ ratio: CGFloat) -> PinLayout { + public func aspectRatio(_ ratio: CGFloat) -> PinLayout { return setAdjustSizeType(.aspectRatio(ratio), { "aspectRatio(\(ratio))" }) } - func aspectRatio(of view: PView) -> PinLayout { + public func aspectRatio(of view: PView) -> PinLayout { let rect = view.getRect(keepTransform: keepTransform) return setAdjustSizeType(.aspectRatio(rect.width / rect.height), { "aspectRatio(of: \(viewDescription(view)))" }) } #if os(iOS) || os(tvOS) - func aspectRatio() -> PinLayout { + public func aspectRatio() -> PinLayout { func context() -> String { return "aspectRatio()" } guard let imageView = view as? UIImageView else { warnWontBeApplied("the layouted must be an UIImageView() to use the aspectRatio() method without parameter.", context) @@ -112,12 +112,12 @@ extension PinLayoutImpl { } #endif - func sizeToFit(_ fitType: FitType) -> PinLayout { + public func sizeToFit(_ fitType: FitType) -> PinLayout { return setAdjustSizeType(fitType.toAdjustSizeType(), { return "sizeToFit(\(fitType.description))" }) } #if os(iOS) || os(tvOS) - func fitSize() -> PinLayout { + public func fitSize() -> PinLayout { return setAdjustSizeType(.fitSizeLegacy, { return "fitSize()" }) } #endif @@ -125,7 +125,7 @@ extension PinLayoutImpl { // // MARK: Private methods -extension PinLayoutImpl { +extension PinLayout { internal func setSize(_ size: CGSize, _ context: Context) -> PinLayout { setWidth(size.width, { return "\(context())'s width" }) setHeight(size.height, { return "\(context())'s height" }) diff --git a/Sources/Impl/PinLayoutImpl+Warning.swift b/Sources/Impl/PinLayoutImpl+Warning.swift index 07c017e6..d8151fae 100644 --- a/Sources/Impl/PinLayoutImpl+Warning.swift +++ b/Sources/Impl/PinLayoutImpl+Warning.swift @@ -30,7 +30,7 @@ fileprivate var numberFormatter: NumberFormatter = { return numberFormatter }() -extension PinLayoutImpl { +extension PinLayout { internal func pointContext(method: String, point: CGPoint) -> String { return "\(method)(to: CGPoint(x: \(point.x), y: \(point.y)))" } diff --git a/Sources/Impl/PinLayoutImpl+WrapContent.swift b/Sources/Impl/PinLayoutImpl+WrapContent.swift index c52e1c38..3e782d26 100644 --- a/Sources/Impl/PinLayoutImpl+WrapContent.swift +++ b/Sources/Impl/PinLayoutImpl+WrapContent.swift @@ -23,28 +23,28 @@ import UIKit import AppKit #endif -extension PinLayoutImpl { - func wrapContent() -> PinLayout { +extension PinLayout { + public func wrapContent() -> PinLayout { return wrapContent(.all, padding: PEdgeInsets(top: 0, left: 0, bottom: 0, right: 0), { return "wrapContent()" }) } - func wrapContent(padding: CGFloat) -> PinLayout { + public func wrapContent(padding: CGFloat) -> PinLayout { return wrapContent(.all, padding: PEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), { return "wrapContent(padding: \(padding)" }) } - func wrapContent(padding: PEdgeInsets) -> PinLayout { + public func wrapContent(padding: PEdgeInsets) -> PinLayout { return wrapContent(.all, padding: padding, { return "wrapContent(padding: \(insetsDescription(padding))" }) } - func wrapContent(_ type: WrapType) -> PinLayout { + public func wrapContent(_ type: WrapType) -> PinLayout { return wrapContent(type, padding: PEdgeInsets(top: 0, left: 0, bottom: 0, right: 0), { return "wrapContent(\(type.description)" }) } - func wrapContent(_ type: WrapType, padding: CGFloat) -> PinLayout { + public func wrapContent(_ type: WrapType, padding: CGFloat) -> PinLayout { return wrapContent(type, padding: PEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), { return "wrapContent(\(type.description), padding: \(padding)" }) } - func wrapContent(_ type: WrapType, padding: PEdgeInsets) -> PinLayout { + public func wrapContent(_ type: WrapType, padding: PEdgeInsets) -> PinLayout { return wrapContent(type, padding: padding, { return "wrapContent(\(type.description), padding: \(insetsDescription(padding))" }) } diff --git a/Sources/Impl/PinLayoutImpl.swift b/Sources/Impl/PinLayoutImpl.swift index bb0fe222..567f942b 100644 --- a/Sources/Impl/PinLayoutImpl.swift +++ b/Sources/Impl/PinLayoutImpl.swift @@ -21,15 +21,15 @@ import Foundation #if os(iOS) || os(tvOS) import UIKit - typealias PView = UIView - typealias PEdgeInsets = UIEdgeInsets + public typealias PView = UIView + public typealias PEdgeInsets = UIEdgeInsets #else import AppKit - typealias PView = NSView - typealias PEdgeInsets = NSEdgeInsets + public typealias PView = NSView + public typealias PEdgeInsets = NSEdgeInsets #endif -class PinLayoutImpl: PinLayout { +public class PinLayout { internal let view: PView internal let keepTransform: Bool @@ -87,7 +87,7 @@ class PinLayoutImpl: PinLayout { } #if os(iOS) || os(tvOS) - var safeArea: PEdgeInsets { + public var safeArea: PEdgeInsets { if #available(iOS 11.0, tvOS 11.0, *) { return view.safeAreaInsets } else { @@ -99,157 +99,157 @@ class PinLayoutImpl: PinLayout { // // top, left, bottom, right // - func top() -> PinLayout { + public func top() -> PinLayout { top({ return "top()" }) return self } - func top(_ value: CGFloat) -> PinLayout { + public func top(_ value: CGFloat) -> PinLayout { return top(value, { return "top(\(value))" }) } - func top(_ percent: Percent) -> PinLayout { + public func top(_ percent: Percent) -> PinLayout { func context() -> String { return "top(\(percent.description))" } guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self } setTop(percent.of(layoutSuperviewRect.height), context) return self } - func top(_ insets: PEdgeInsets) -> PinLayout { + public func top(_ insets: PEdgeInsets) -> PinLayout { return top(insets.top, { return "top(\(insetsDescription(insets))" }) } - func left() -> PinLayout { + public func left() -> PinLayout { return left({ return "left()" }) } - func left(_ value: CGFloat) -> PinLayout { + public func left(_ value: CGFloat) -> PinLayout { return left(value, { return "left(\(value))" }) } - func left(_ percent: Percent) -> PinLayout { + public func left(_ percent: Percent) -> PinLayout { return left(percent, { return "left(\(percent.description))" }) } - func left(_ insets: PEdgeInsets) -> PinLayout { + public func left(_ insets: PEdgeInsets) -> PinLayout { return left(insets.left, { return "left(\(insetsDescription(insets))" }) } - func start() -> PinLayout { + public func start() -> PinLayout { func context() -> String { return "start()" } return isLTR() ? left(context) : right(context) } - func start(_ value: CGFloat) -> PinLayout { + public func start(_ value: CGFloat) -> PinLayout { func context() -> String { return "start(\(value))" } return isLTR() ? left(value, context) : right(value, context) } - func start(_ percent: Percent) -> PinLayout { + public func start(_ percent: Percent) -> PinLayout { func context() -> String { return "start(\(percent.description))" } return isLTR() ? left(percent, context) : right(percent, context) } - func start(_ insets: PEdgeInsets) -> PinLayout { + public func start(_ insets: PEdgeInsets) -> PinLayout { func context() -> String { return "start(\(insetsDescription(insets))" } return isLTR() ? left(insets.left, context) : right(insets.right, context) } - func bottom() -> PinLayout { + public func bottom() -> PinLayout { return bottom({ return "bottom()" }) } - func bottom(_ value: CGFloat) -> PinLayout { + public func bottom(_ value: CGFloat) -> PinLayout { return bottom(value, { return "bottom(\(value))" }) } - func bottom(_ percent: Percent) -> PinLayout { + public func bottom(_ percent: Percent) -> PinLayout { return bottom(percent, { return "bottom(\(percent.description))" }) } - func bottom(_ insets: PEdgeInsets) -> PinLayout { + public func bottom(_ insets: PEdgeInsets) -> PinLayout { return bottom(insets.bottom, { return "bottom(\(insetsDescription(insets))" }) } - func right() -> PinLayout { + public func right() -> PinLayout { return right({ return "right()" }) } - func right(_ value: CGFloat) -> PinLayout { + public func right(_ value: CGFloat) -> PinLayout { return right(value, { return "right(\(value))" }) } - func right(_ percent: Percent) -> PinLayout { + public func right(_ percent: Percent) -> PinLayout { return right(percent, { return "right(\(percent.description))" }) } - func right(_ insets: PEdgeInsets) -> PinLayout { + public func right(_ insets: PEdgeInsets) -> PinLayout { return right(insets.right, { return "right(\(insetsDescription(insets))" }) } - func end() -> PinLayout { + public func end() -> PinLayout { func context() -> String { return "end()" } return isLTR() ? right(context) : left(context) } - func end(_ value: CGFloat) -> PinLayout { + public func end(_ value: CGFloat) -> PinLayout { func context() -> String { return "end(\(value))" } return isLTR() ? right(value, context) : left(value, context) } - func end(_ percent: Percent) -> PinLayout { + public func end(_ percent: Percent) -> PinLayout { func context() -> String { return "end(\(percent.description))" } return isLTR() ? right(percent, context) : left(percent, context) } - func end(_ insets: PEdgeInsets) -> PinLayout { + public func end(_ insets: PEdgeInsets) -> PinLayout { func context() -> String { return "end(\(insetsDescription(insets))" } return isLTR() ? right(insets.right, context) : left(insets.left, context) } - func hCenter() -> PinLayout { + public func hCenter() -> PinLayout { func context() -> String { return "hCenter()" } guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self } setHorizontalCenter(layoutSuperviewRect.width / 2, context) return self } - func hCenter(_ value: CGFloat) -> PinLayout { + public 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 } - func hCenter(_ percent: Percent) -> PinLayout { + public func hCenter(_ percent: Percent) -> PinLayout { func context() -> String { return "hCenter(\(percent.description))" } guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self } setHorizontalCenter((layoutSuperviewRect.width / 2) + percent.of(layoutSuperviewRect.width), context) return self } - func vCenter() -> PinLayout { + public func vCenter() -> PinLayout { func context() -> String { return "vCenter()" } guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self } setVerticalCenter(layoutSuperviewRect.height / 2, context) return self } - func vCenter(_ value: CGFloat) -> PinLayout { + public 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 } - func vCenter(_ percent: Percent) -> PinLayout { + public 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 } - func all() -> PinLayout { + public func all() -> PinLayout { top({ "all() top coordinate" }) bottom({ "all() bottom coordinate" }) right({ "all() right coordinate" }) @@ -257,7 +257,7 @@ class PinLayoutImpl: PinLayout { return self } - func all(_ value: CGFloat) -> PinLayout { + public func all(_ value: CGFloat) -> PinLayout { top(value, { "all(\(value)) top coordinate" }) bottom(value, { "all(\(value)) bottom coordinate" }) left(value, { "all(\(value)) left coordinate" }) @@ -265,7 +265,7 @@ class PinLayoutImpl: PinLayout { return self } - func all(_ insets: PEdgeInsets) -> PinLayout { + public func all(_ insets: PEdgeInsets) -> PinLayout { top(insets.top, { "all(\(insets)) top coordinate" }) bottom(insets.bottom, { "all(\(insets)) bottom coordinate" }) left(insets.left, { "all(\(insets)) left coordinate" }) @@ -273,49 +273,49 @@ class PinLayoutImpl: PinLayout { return self } - func horizontally() -> PinLayout { + public func horizontally() -> PinLayout { right({ "horizontally() right coordinate" }) left({ "horizontally() left coordinate" }) return self } - func horizontally(_ value: CGFloat) -> PinLayout { + public func horizontally(_ value: CGFloat) -> PinLayout { left(value, { return "horizontally(\(value)) left coordinate" }) right(value, { return "horizontally(\(value)) right coordinate" }) return self } - func horizontally(_ percent: Percent) -> PinLayout { + public func horizontally(_ percent: Percent) -> PinLayout { left(percent, { return "horizontally(\(percent.description)) left coordinate" }) right(percent, { return "horizontally(\(percent.description)) right coordinate" }) return self } - func horizontally(_ insets: PEdgeInsets) -> PinLayout { + public func horizontally(_ insets: PEdgeInsets) -> PinLayout { left(insets.left, { return "horizontally(\(insets)) left coordinate" }) right(insets.right, { return "horizontally(\(insets)) right coordinate" }) return self } - func vertically() -> PinLayout { + public func vertically() -> PinLayout { top({ "vertically() top coordinate" }) bottom({ "vertically() bottom coordinate" }) return self } - func vertically(_ value: CGFloat) -> PinLayout { + public func vertically(_ value: CGFloat) -> PinLayout { top(value, { return "vertically(\(value)) top coordinate" }) bottom(value, { return "vertically(\(value)) bottom coordinate" }) return self } - func vertically(_ percent: Percent) -> PinLayout { + public func vertically(_ percent: Percent) -> PinLayout { top(percent, { return "vertically(\(percent.description)) top coordinate" }) bottom(percent, { return "vertically(\(percent.description)) bottom coordinate" }) return self } - func vertically(_ insets: PEdgeInsets) -> PinLayout { + public func vertically(_ insets: PEdgeInsets) -> PinLayout { top(insets.top, { return "vertically(\(insets)) top coordinate" }) bottom(insets.bottom, { return "vertically(\(insets)) bottom coordinate" }) return self @@ -324,7 +324,7 @@ class PinLayoutImpl: PinLayout { // // top, left, bottom, right // - func top(to edge: VerticalEdge) -> PinLayout { + public func top(to edge: VerticalEdge) -> PinLayout { func context() -> String { return relativeEdgeContext(method: "top", edge: edge) } if let coordinate = computeCoordinate(forEdge: edge, context) { setTop(coordinate, context) @@ -332,7 +332,7 @@ class PinLayoutImpl: PinLayout { return self } - func vCenter(to edge: VerticalEdge) -> PinLayout { + public func vCenter(to edge: VerticalEdge) -> PinLayout { func context() -> String { return relativeEdgeContext(method: "vCenter", edge: edge) } if let coordinate = computeCoordinate(forEdge: edge, context) { setVerticalCenter(coordinate, context) @@ -340,7 +340,7 @@ class PinLayoutImpl: PinLayout { return self } - func bottom(to edge: VerticalEdge) -> PinLayout { + public func bottom(to edge: VerticalEdge) -> PinLayout { func context() -> String { return relativeEdgeContext(method: "bottom", edge: edge) } if let coordinate = computeCoordinate(forEdge: edge, context) { setBottom(coordinate, context) @@ -348,7 +348,7 @@ class PinLayoutImpl: PinLayout { return self } - func left(to edge: HorizontalEdge) -> PinLayout { + public func left(to edge: HorizontalEdge) -> PinLayout { func context() -> String { return relativeEdgeContext(method: "left", edge: edge) } if let coordinate = computeCoordinate(forEdge: edge, context) { setLeft(coordinate, context) @@ -356,7 +356,7 @@ class PinLayoutImpl: PinLayout { return self } - func hCenter(to edge: HorizontalEdge) -> PinLayout { + public func hCenter(to edge: HorizontalEdge) -> PinLayout { func context() -> String { return relativeEdgeContext(method: "hCenter", edge: edge) } if let coordinate = computeCoordinate(forEdge: edge, context) { setHorizontalCenter(coordinate, context) @@ -364,7 +364,7 @@ class PinLayoutImpl: PinLayout { return self } - func right(to edge: HorizontalEdge) -> PinLayout { + public func right(to edge: HorizontalEdge) -> PinLayout { func context() -> String { return relativeEdgeContext(method: "right", edge: edge) } if let coordinate = computeCoordinate(forEdge: edge, context) { setRight(coordinate, context) @@ -372,7 +372,7 @@ class PinLayoutImpl: PinLayout { return self } - func start(to edge: HorizontalEdge) -> PinLayout { + public func start(to edge: HorizontalEdge) -> PinLayout { func context() -> String { return relativeEdgeContext(method: "start", edge: edge) } if let coordinate = computeCoordinate(forEdge: edge, context) { setStart(coordinate, context) @@ -380,7 +380,7 @@ class PinLayoutImpl: PinLayout { return self } - func end(to edge: HorizontalEdge) -> PinLayout { + public func end(to edge: HorizontalEdge) -> PinLayout { func context() -> String { return relativeEdgeContext(method: "end", edge: edge) } if let coordinate = computeCoordinate(forEdge: edge, context) { setEnd(coordinate, context) @@ -393,7 +393,7 @@ class PinLayoutImpl: PinLayout { // centerLeft, center, centerRight, // bottomLeft, bottomCenter, bottomRight, // - func topLeft(to anchor: Anchor) -> PinLayout { + public func topLeft(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "topLeft", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setTopLeft(coordinatesList[0], context) @@ -401,7 +401,7 @@ class PinLayoutImpl: PinLayout { return self } - func topLeft() -> PinLayout { + public func topLeft() -> PinLayout { return topLeft({ return "topLeft()" }) } @@ -410,7 +410,7 @@ class PinLayoutImpl: PinLayout { return self } - func topStart(to anchor: Anchor) -> PinLayout { + public func topStart(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "topStart", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setTop(coordinatesList[0].y, context) @@ -419,12 +419,12 @@ class PinLayoutImpl: PinLayout { return self } - func topStart() -> PinLayout { + public func topStart() -> PinLayout { func context() -> String { return "topStart()" } return isLTR() ? topLeft(context) : topRight(context) } - func topCenter(to anchor: Anchor) -> PinLayout { + public func topCenter(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "topCenter", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setTopCenter(coordinatesList[0], context) @@ -432,14 +432,14 @@ class PinLayoutImpl: PinLayout { return self } - func topCenter() -> PinLayout { + public func topCenter() -> PinLayout { func context() -> String { return "topCenter()" } guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self } setTopCenter(CGPoint(x: layoutSuperviewRect.width / 2, y: 0), context) return self } - func topRight(to anchor: Anchor) -> PinLayout { + public func topRight(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "topRight", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setTopRight(coordinatesList[0], context) @@ -447,7 +447,7 @@ class PinLayoutImpl: PinLayout { return self } - func topRight() -> PinLayout { + public func topRight() -> PinLayout { return topRight({ return "topRight()" }) } @@ -457,7 +457,7 @@ class PinLayoutImpl: PinLayout { return self } - func topEnd(to anchor: Anchor) -> PinLayout { + public func topEnd(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "topEnd", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setTop(coordinatesList[0].y, context) @@ -466,12 +466,12 @@ class PinLayoutImpl: PinLayout { return self } - func topEnd() -> PinLayout { + public func topEnd() -> PinLayout { func context() -> String { return "topEnd()" } return isLTR() ? topRight(context) : topLeft(context) } - func centerLeft(to anchor: Anchor) -> PinLayout { + public func centerLeft(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "centerLeft", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setCenterLeft(coordinatesList[0], context) @@ -479,7 +479,7 @@ class PinLayoutImpl: PinLayout { return self } - func centerLeft() -> PinLayout { + public func centerLeft() -> PinLayout { return centerLeft({ return "centerLeft()" }) } @@ -489,7 +489,7 @@ class PinLayoutImpl: PinLayout { return self } - func centerStart(to anchor: Anchor) -> PinLayout { + public func centerStart(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "centerStart", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setVerticalCenter(coordinatesList[0].y, context) @@ -498,12 +498,12 @@ class PinLayoutImpl: PinLayout { return self } - func centerStart() -> PinLayout { + public func centerStart() -> PinLayout { func context() -> String { return "centerStart()" } return isLTR() ? centerLeft(context) : centerRight(context) } - func center(to anchor: Anchor) -> PinLayout { + public func center(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "center", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setCenter(coordinatesList[0], context) @@ -511,14 +511,14 @@ class PinLayoutImpl: PinLayout { return self } - func center() -> PinLayout { + public 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 } - func centerRight(to anchor: Anchor) -> PinLayout { + public func centerRight(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "centerRight", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setCenterRight(coordinatesList[0], context) @@ -526,7 +526,7 @@ class PinLayoutImpl: PinLayout { return self } - func centerRight() -> PinLayout { + public func centerRight() -> PinLayout { return centerRight({ return "centerRight()" }) } @@ -536,7 +536,7 @@ class PinLayoutImpl: PinLayout { return self } - func centerEnd(to anchor: Anchor) -> PinLayout { + public func centerEnd(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "centerEnd", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setVerticalCenter(coordinatesList[0].y, context) @@ -545,12 +545,12 @@ class PinLayoutImpl: PinLayout { return self } - func centerEnd() -> PinLayout { + public func centerEnd() -> PinLayout { func context() -> String { return "centerEnd()" } return isLTR() ? centerRight(context) : centerLeft(context) } - func bottomLeft(to anchor: Anchor) -> PinLayout { + public func bottomLeft(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "bottomLeft", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setBottomLeft(coordinatesList[0], context) @@ -558,7 +558,7 @@ class PinLayoutImpl: PinLayout { return self } - func bottomLeft() -> PinLayout { + public func bottomLeft() -> PinLayout { return bottomLeft({ return "bottomLeft()" }) } @@ -568,7 +568,7 @@ class PinLayoutImpl: PinLayout { return self } - func bottomStart(to anchor: Anchor) -> PinLayout { + public func bottomStart(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "bottomStart", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setBottom(coordinatesList[0].y, context) @@ -577,12 +577,12 @@ class PinLayoutImpl: PinLayout { return self } - func bottomStart() -> PinLayout { + public func bottomStart() -> PinLayout { func context() -> String { return "bottomStart()" } return isLTR() ? bottomLeft(context) : bottomRight(context) } - func bottomCenter(to anchor: Anchor) -> PinLayout { + public func bottomCenter(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "bottomCenter", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setBottomCenter(coordinatesList[0], context) @@ -590,14 +590,14 @@ class PinLayoutImpl: PinLayout { return self } - func bottomCenter() -> PinLayout { + public func bottomCenter() -> PinLayout { func context() -> String { return "bottomCenter()" } guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self } setBottomCenter(CGPoint(x: layoutSuperviewRect.width / 2, y: layoutSuperviewRect.height), context) return self } - func bottomRight(to anchor: Anchor) -> PinLayout { + public func bottomRight(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "bottomRight", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setBottomRight(coordinatesList[0], context) @@ -605,7 +605,7 @@ class PinLayoutImpl: PinLayout { return self } - func bottomRight() -> PinLayout { + public func bottomRight() -> PinLayout { return bottomRight({ return "bottomRight()" }) } @@ -615,7 +615,7 @@ class PinLayoutImpl: PinLayout { return self } - func bottomEnd(to anchor: Anchor) -> PinLayout { + public func bottomEnd(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "bottomEnd", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { setBottom(coordinatesList[0].y, context) @@ -624,7 +624,7 @@ class PinLayoutImpl: PinLayout { return self } - func bottomEnd() -> PinLayout { + public func bottomEnd() -> PinLayout { func context() -> String { return "bottomEnd()" } return isLTR() ? bottomRight(context) : bottomLeft(context) } @@ -632,75 +632,75 @@ class PinLayoutImpl: PinLayout { // // width, height // - func width(_ width: CGFloat) -> PinLayout { + public func width(_ width: CGFloat) -> PinLayout { return setWidth(width, { return "width(\(width))" }) } - func width(_ percent: Percent) -> PinLayout { + public 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) } - func width(of view: PView) -> PinLayout { + public func width(of view: PView) -> PinLayout { let rect = view.getRect(keepTransform: keepTransform) return setWidth(rect.width, { return "width(of: \(viewDescription(view)))" }) } - func minWidth(_ width: CGFloat) -> PinLayout { + public func minWidth(_ width: CGFloat) -> PinLayout { setMinWidth(width, { return "minWidth(\(width))" }) return self } - func minWidth(_ percent: Percent) -> PinLayout { + public 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) } - func maxWidth(_ width: CGFloat) -> PinLayout { + public func maxWidth(_ width: CGFloat) -> PinLayout { setMaxWidth(width, { return "maxWidth(\(width))" }) return self } - func maxWidth(_ percent: Percent) -> PinLayout { + public 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) } - func height(_ height: CGFloat) -> PinLayout { + public func height(_ height: CGFloat) -> PinLayout { return setHeight(height, { return "height(\(height))" }) } - func height(_ percent: Percent) -> PinLayout { + public 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) } - func height(of view: PView) -> PinLayout { + public func height(of view: PView) -> PinLayout { let rect = view.getRect(keepTransform: keepTransform) return setHeight(rect.height, { return "height(of: \(viewDescription(view)))" }) } - func minHeight(_ height: CGFloat) -> PinLayout { + public func minHeight(_ height: CGFloat) -> PinLayout { setMinHeight(height, { return "minHeight(\(height))" }) return self } - func minHeight(_ percent: Percent) -> PinLayout { + public 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) } - func maxHeight(_ height: CGFloat) -> PinLayout { + public func maxHeight(_ height: CGFloat) -> PinLayout { setMaxHeight(height, { return "maxHeight(\(height))" }) return self } - func maxHeight(_ percent: Percent) -> PinLayout { + public func maxHeight(_ percent: Percent) -> PinLayout { func context() -> String { return "maxHeight(\(percent.description))" } guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self } return setMaxHeight(percent.of(layoutSuperviewRect.height), context) @@ -709,12 +709,12 @@ class PinLayoutImpl: PinLayout { // // justify, align // - func justify(_ value: HorizontalAlign) -> PinLayout { + public func justify(_ value: HorizontalAlign) -> PinLayout { justify = value return self } - func align(_ value: VerticalAlign) -> PinLayout { + public func align(_ value: VerticalAlign) -> PinLayout { align = value return self } @@ -722,12 +722,12 @@ class PinLayoutImpl: PinLayout { // // Margins // - func marginTop(_ value: CGFloat) -> PinLayout { + public func marginTop(_ value: CGFloat) -> PinLayout { marginTop = value return self } - func marginTop(_ percent: Percent) -> PinLayout { + public func marginTop(_ percent: Percent) -> PinLayout { func context() -> String { return "marginTop(\(percent.description))" } return marginTop(percent, context) } @@ -738,12 +738,12 @@ class PinLayoutImpl: PinLayout { return self } - func marginLeft(_ value: CGFloat) -> PinLayout { + public func marginLeft(_ value: CGFloat) -> PinLayout { marginLeft = value return self } - func marginLeft(_ percent: Percent) -> PinLayout { + public func marginLeft(_ percent: Percent) -> PinLayout { func context() -> String { return "marginLeft(\(percent.description))" } return marginLeft(percent, context) } @@ -754,12 +754,12 @@ class PinLayoutImpl: PinLayout { return self } - func marginBottom(_ value: CGFloat) -> PinLayout { + public func marginBottom(_ value: CGFloat) -> PinLayout { marginBottom = value return self } - func marginBottom(_ percent: Percent) -> PinLayout { + public func marginBottom(_ percent: Percent) -> PinLayout { func context() -> String { return "marginBottom(\(percent.description))" } return marginBottom(percent, context) } @@ -770,12 +770,12 @@ class PinLayoutImpl: PinLayout { return self } - func marginRight(_ value: CGFloat) -> PinLayout { + public func marginRight(_ value: CGFloat) -> PinLayout { marginRight = value return self } - func marginRight(_ percent: Percent) -> PinLayout { + public func marginRight(_ percent: Percent) -> PinLayout { func context() -> String { return "marginRight(\(percent.description))" } return marginRight(percent, context) } @@ -787,32 +787,32 @@ class PinLayoutImpl: PinLayout { } @discardableResult - func marginStart(_ value: CGFloat) -> PinLayout { + public func marginStart(_ value: CGFloat) -> PinLayout { return isLTR() ? marginLeft(value) : marginRight(value) } - func marginStart(_ percent: Percent) -> PinLayout { + public func marginStart(_ percent: Percent) -> PinLayout { func context() -> String { return "marginStart(\(percent.description))" } return isLTR() ? marginLeft(percent, context) : marginRight(percent, context) } @discardableResult - func marginEnd(_ value: CGFloat) -> PinLayout { + public func marginEnd(_ value: CGFloat) -> PinLayout { return isLTR() ? marginRight(value) : marginLeft(value) } - func marginEnd(_ percent: Percent) -> PinLayout { + public func marginEnd(_ percent: Percent) -> PinLayout { func context() -> String { return "marginEnd(\(percent.description))" } return isLTR() ? marginRight(percent, context) : marginLeft(percent, context) } - func marginHorizontal(_ value: CGFloat) -> PinLayout { + public func marginHorizontal(_ value: CGFloat) -> PinLayout { marginLeft = value marginRight = value return self } - func marginHorizontal(_ percent: Percent) -> PinLayout { + public func marginHorizontal(_ percent: Percent) -> PinLayout { func context() -> String { return "marginHorizontal(\(percent.description))" } return marginHorizontal(percent, context) } @@ -821,13 +821,13 @@ class PinLayoutImpl: PinLayout { return marginLeft(percent, context).marginRight(percent, context) } - func marginVertical(_ value: CGFloat) -> PinLayout { + public func marginVertical(_ value: CGFloat) -> PinLayout { marginTop = value marginBottom = value return self } - func marginVertical(_ percent: Percent) -> PinLayout { + public func marginVertical(_ percent: Percent) -> PinLayout { func context() -> String { return "marginVertical(\(percent.description))" } return marginVertical(percent, context) } @@ -836,7 +836,7 @@ class PinLayoutImpl: PinLayout { return marginTop(percent, context).marginBottom(percent, context) } - func margin(_ insets: PEdgeInsets) -> PinLayout { + public func margin(_ insets: PEdgeInsets) -> PinLayout { marginTop = insets.top marginBottom = insets.bottom marginLeft = insets.left @@ -846,7 +846,7 @@ class PinLayoutImpl: PinLayout { #if os(iOS) || os(tvOS) @available(tvOS 11.0, iOS 11.0, *) - func margin(_ directionalInsets: NSDirectionalEdgeInsets) -> PinLayout { + public func margin(_ directionalInsets: NSDirectionalEdgeInsets) -> PinLayout { marginTop = directionalInsets.top marginBottom = directionalInsets.bottom marginStart(directionalInsets.leading) @@ -855,7 +855,7 @@ class PinLayoutImpl: PinLayout { } #endif - func margin(_ value: CGFloat) -> PinLayout { + public func margin(_ value: CGFloat) -> PinLayout { marginTop = value marginLeft = value marginBottom = value @@ -863,7 +863,7 @@ class PinLayoutImpl: PinLayout { return self } - func margin(_ percent: Percent) -> PinLayout { + public func margin(_ percent: Percent) -> PinLayout { func context() -> String { return "margin(\(percent.description))" } return marginTop(percent, context) .marginLeft(percent, context) @@ -871,7 +871,7 @@ class PinLayoutImpl: PinLayout { .marginRight(percent, context) } - func margin(_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) -> PinLayout { + public func margin(_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) -> PinLayout { marginTop = top marginLeft = left marginBottom = bottom @@ -879,7 +879,7 @@ class PinLayoutImpl: PinLayout { return self } - func margin(_ top: Percent, _ left: Percent, _ bottom: Percent, _ right: Percent) -> PinLayout { + public 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)" } @@ -889,7 +889,7 @@ class PinLayoutImpl: PinLayout { .marginRight(right, context) } - func margin(_ vertical: CGFloat, _ horizontal: CGFloat) -> PinLayout { + public func margin(_ vertical: CGFloat, _ horizontal: CGFloat) -> PinLayout { marginTop = vertical marginLeft = horizontal marginBottom = vertical @@ -897,12 +897,12 @@ class PinLayoutImpl: PinLayout { return self } - func margin(_ vertical: Percent, _ horizontal: Percent) -> PinLayout { + public 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) } - func margin(_ top: CGFloat, _ horizontal: CGFloat, _ bottom: CGFloat) -> PinLayout { + public func margin(_ top: CGFloat, _ horizontal: CGFloat, _ bottom: CGFloat) -> PinLayout { marginTop = top marginLeft = horizontal marginBottom = bottom @@ -910,12 +910,12 @@ class PinLayoutImpl: PinLayout { return self } - func margin(_ top: Percent, _ horizontal: Percent, _ bottom: Percent) -> PinLayout { + public 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) } - func pinEdges() -> PinLayout { + public func pinEdges() -> PinLayout { shouldPinEdges = true return self } @@ -924,7 +924,7 @@ class PinLayoutImpl: PinLayout { // // MARK: Private methods // -extension PinLayoutImpl { +extension PinLayout { internal func layoutSuperviewRect(_ context: Context) -> CGRect? { if let superview = view.superview { return superview.getRect(keepTransform: keepTransform) diff --git a/Sources/NSView+PinLayout.swift b/Sources/NSView+PinLayout.swift index c683c02e..59438fa2 100644 --- a/Sources/NSView+PinLayout.swift +++ b/Sources/NSView+PinLayout.swift @@ -24,11 +24,11 @@ import AppKit public extension NSView { public var pin: PinLayout { - return PinLayoutImpl(view: self, keepTransform: true) + return PinLayout(view: self, keepTransform: true) } public var pinFrame: PinLayout { - return PinLayoutImpl(view: self, keepTransform: false) + return PinLayout(view: self, keepTransform: false) } public var anchor: AnchorList { diff --git a/Sources/ObjectiveC/PinLayoutObjCImpl.swift b/Sources/ObjectiveC/PinLayoutObjCImpl.swift index 87ad03a7..6fc96770 100644 --- a/Sources/ObjectiveC/PinLayoutObjCImpl.swift +++ b/Sources/ObjectiveC/PinLayoutObjCImpl.swift @@ -24,10 +24,10 @@ import AppKit #endif @objc class PinLayoutObjCImpl: NSObject, PinLayoutObjC { - fileprivate var impl: PinLayoutImpl? + fileprivate var impl: PinLayout? init(view: PView, keepTransform: Bool) { - impl = PinLayoutImpl(view: view, keepTransform: keepTransform) + impl = PinLayout(view: view, keepTransform: keepTransform) } deinit { diff --git a/Sources/PinLayout.swift b/Sources/PinLayout.swift index a94e6756..64411f4f 100644 --- a/Sources/PinLayout.swift +++ b/Sources/PinLayout.swift @@ -16,7 +16,7 @@ // 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 @@ -589,3 +589,4 @@ public protocol PinLayout { */ func layout() } + */ diff --git a/Sources/UIView+PinLayout.swift b/Sources/UIView+PinLayout.swift index 36121e59..fb4b74f8 100644 --- a/Sources/UIView+PinLayout.swift +++ b/Sources/UIView+PinLayout.swift @@ -24,11 +24,11 @@ import UIKit public extension UIView { public var pin: PinLayout { - return PinLayoutImpl(view: self, keepTransform: true) + return PinLayout(view: self, keepTransform: true) } public var pinFrame: PinLayout { - return PinLayoutImpl(view: self, keepTransform: false) + return PinLayout(view: self, keepTransform: false) } @objc public var anchor: AnchorList { From b2d76e626ba432ec6623586f33e7c22e03fb2661 Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Tue, 12 Jun 2018 18:18:33 -0400 Subject: [PATCH 02/11] Extract protocol Layoutable --- PinLayout.xcodeproj/project.pbxproj | 8 +++ Sources/Impl/Coordinates.swift | 42 +++++++------- Sources/Impl/PinLayoutImpl+Coordinates.swift | 12 ++-- Sources/Impl/PinLayoutImpl+Layouting.swift | 19 +------ Sources/Impl/PinLayoutImpl+Relative.swift | 58 ++++++++++---------- Sources/Impl/PinLayoutImpl+Size.swift | 4 +- Sources/Impl/PinLayoutImpl+Warning.swift | 17 +++--- Sources/Impl/PinLayoutImpl.swift | 30 +++++----- Sources/Impl/TypesImpl.swift | 30 +++++----- Sources/Impl/View+LTR.swift | 4 +- Sources/Layoutable.swift | 44 +++++++++++++++ Sources/NSView+PinLayout.swift | 18 +++--- Sources/ObjectiveC/PinLayoutObjCImpl.swift | 10 +++- Sources/UIView+PinLayout.swift | 20 ++----- Sources/View+Rect.swift | 12 ++-- Tests/BasicView.swift | 8 +-- Tests/Common/AdjustSizeSpec.swift | 2 +- Tests/Common/AspectRatioTests.swift | 2 +- Tests/Common/JustifyAlignSpec.swift | 2 +- Tests/Common/LayoutMethodSpec.swift | 2 +- Tests/Common/MinMaxWidthHeightSpec.swift | 2 +- Tests/Common/WarningSpec.swift | 2 +- Tests/Common/WrapContentSpec.swift | 2 +- 23 files changed, 191 insertions(+), 159 deletions(-) create mode 100644 Sources/Layoutable.swift diff --git a/PinLayout.xcodeproj/project.pbxproj b/PinLayout.xcodeproj/project.pbxproj index bcbe9fef..db7c4a1e 100644 --- a/PinLayout.xcodeproj/project.pbxproj +++ b/PinLayout.xcodeproj/project.pbxproj @@ -53,6 +53,9 @@ 24D18D241F3E37DD008129EF /* Pin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D231F3E37DD008129EF /* Pin.swift */; }; 24D18D261F3E5EA5008129EF /* Pin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D231F3E37DD008129EF /* Pin.swift */; }; 32A65F57D5D8D5204831FF3A /* Pods_PinLayoutTests_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 417E52FC81E208F91CF03C1D /* Pods_PinLayoutTests_iOS.framework */; }; + C82DC20C20CE9F6800B7ACF5 /* Layoutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82DC20B20CE9F6800B7ACF5 /* Layoutable.swift */; }; + C82DC20D20CE9F6800B7ACF5 /* Layoutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82DC20B20CE9F6800B7ACF5 /* Layoutable.swift */; }; + C82DC20E20CE9F6800B7ACF5 /* Layoutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82DC20B20CE9F6800B7ACF5 /* Layoutable.swift */; }; DF1A5CBB208106A900725EF5 /* UIView+PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1A5CBA208106A900725EF5 /* UIView+PinLayout.swift */; }; DF1A5D0420812DE100725EF5 /* UIView+PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1A5CBA208106A900725EF5 /* UIView+PinLayout.swift */; }; DF1A5D202084C94700725EF5 /* PinLayoutTestMacOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1A5D1F2084C94700725EF5 /* PinLayoutTestMacOS.swift */; }; @@ -219,6 +222,7 @@ A02D58138C6BA063EB3E8E66 /* Pods-PinLayoutTests-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PinLayoutTests-iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-PinLayoutTests-iOS/Pods-PinLayoutTests-iOS.release.xcconfig"; sourceTree = ""; }; B7A69A7C17E9071CF457C39A /* Pods_PinLayoutTests_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PinLayoutTests_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BC74F9FA5B66BF5C299B7581 /* Pods-PinLayoutTests-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PinLayoutTests-macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PinLayoutTests-macOS/Pods-PinLayoutTests-macOS.debug.xcconfig"; sourceTree = ""; }; + C82DC20B20CE9F6800B7ACF5 /* Layoutable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Layoutable.swift; sourceTree = ""; }; C8BDEE8FC7F6D6F36D69AE89 /* Pods-PinLayoutTests-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PinLayoutTests-iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PinLayoutTests-iOS/Pods-PinLayoutTests-iOS.debug.xcconfig"; sourceTree = ""; }; DF1A5CBA208106A900725EF5 /* UIView+PinLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+PinLayout.swift"; sourceTree = ""; }; DF1A5CBC208106C900725EF5 /* NSView+PinLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSView+PinLayout.swift"; sourceTree = ""; }; @@ -355,6 +359,7 @@ DFC97CA61E8A8F2C001545D5 /* PinLayout.swift */, 24D18D231F3E37DD008129EF /* Pin.swift */, DFF222CC20B999BD00AC2A84 /* Types.swift */, + C82DC20B20CE9F6800B7ACF5 /* Layoutable.swift */, DF1A5CBA208106A900725EF5 /* UIView+PinLayout.swift */, DF1A5CBC208106C900725EF5 /* NSView+PinLayout.swift */, DFA06B031E8B38B300B6D5E7 /* Impl */, @@ -834,6 +839,7 @@ 243B12BC1FC393580072A9C3 /* Percent.swift in Sources */, DFB3ECB72062A937005F226B /* PinSafeArea.swift in Sources */, DF96F30B20CB5DDD007CA714 /* View+Rect.swift in Sources */, + C82DC20E20CE9F6800B7ACF5 /* Layoutable.swift in Sources */, DFEAF75420C9667D00E33147 /* PinLayoutImpl+Size.swift in Sources */, DF1A5D0420812DE100725EF5 /* UIView+PinLayout.swift in Sources */, 24B02B091F2A713000C18179 /* Filters.swift in Sources */, @@ -863,6 +869,7 @@ 2475B6D11FC37C8C0054CADD /* View+LTR.swift in Sources */, DF96F30920CB5DB7007CA714 /* View+Rect.swift in Sources */, DFEAF71220C8081800E33147 /* PinLayoutImpl+Size.swift in Sources */, + C82DC20C20CE9F6800B7ACF5 /* Layoutable.swift in Sources */, DF96F30E20CB6362007CA714 /* PinLayoutObjCImpl.swift in Sources */, DFC97CA71E8A8F2C001545D5 /* PinLayout.swift in Sources */, 2475B6CC1FC37C1C0054CADD /* PinLayoutImpl+Warning.swift in Sources */, @@ -946,6 +953,7 @@ DF1A5D442084CFD600725EF5 /* View+LTR.swift in Sources */, DF1A5D352084CFC100725EF5 /* NSView+PinLayout.swift in Sources */, DF96F30A20CB5DDC007CA714 /* View+Rect.swift in Sources */, + C82DC20D20CE9F6800B7ACF5 /* Layoutable.swift in Sources */, DFEAF75320C9667C00E33147 /* PinLayoutImpl+Size.swift in Sources */, DF1A5D3A2084CFC600725EF5 /* UIView+PinLayout.swift in Sources */, DFED155120853085009EF9A7 /* PinLayout.swift in Sources */, diff --git a/Sources/Impl/Coordinates.swift b/Sources/Impl/Coordinates.swift index f900bfa7..a83a81f5 100644 --- a/Sources/Impl/Coordinates.swift +++ b/Sources/Impl/Coordinates.swift @@ -23,69 +23,69 @@ import UIKit import AppKit #endif -public func _pinlayoutSetUnitTest(displayScale: CGFloat) { - Coordinates.displayScale = displayScale -} +#if os(iOS) || os(tvOS) +internal var displayScale: CGFloat = UIScreen.main.scale +#elseif os(OSX) +internal var displayScale: CGFloat = NSScreen.main?.backingScaleFactor ?? 2.0 +#endif +internal var onePixelLength: CGFloat = 1 / displayScale -final class Coordinates { - #if os(iOS) || os(tvOS) - internal static var displayScale: CGFloat = UIScreen.main.scale - #elseif os(OSX) - internal static var displayScale: CGFloat = NSScreen.main?.backingScaleFactor ?? 2.0 - #endif - internal static var onePixelLength: CGFloat = 1 / displayScale +public func _pinlayoutSetUnitTest(scale: CGFloat) { + displayScale = scale +} - static func hCenter(_ view: PView, keepTransform: Bool) -> CGFloat { +final class Coordinates { + static func hCenter(_ view: View, keepTransform: Bool) -> CGFloat { let rect = view.getRect(keepTransform: keepTransform) return rect.minX + (rect.width / 2) } - static func vCenter(_ view: PView, keepTransform: Bool) -> CGFloat { + static func vCenter(_ view: View, keepTransform: Bool) -> CGFloat { let rect = view.getRect(keepTransform: keepTransform) return rect.minY + (rect.height / 2) } - static func topLeft(_ view: PView, keepTransform: Bool) -> CGPoint { + static func topLeft(_ view: View, keepTransform: Bool) -> CGPoint { let rect = view.getRect(keepTransform: keepTransform) return CGPoint(x: rect.minX, y: rect.minY) } - static func topCenter(_ view: PView, keepTransform: Bool) -> CGPoint { + static func topCenter(_ view: View, keepTransform: Bool) -> CGPoint { let rect = view.getRect(keepTransform: keepTransform) return CGPoint(x: rect.minX + (rect.width / 2), y: rect.minY) } - static func topRight(_ view: PView, keepTransform: Bool) -> CGPoint { + static func topRight(_ view: View, keepTransform: Bool) -> CGPoint { let rect = view.getRect(keepTransform: keepTransform) return CGPoint(x: rect.minX + rect.width, y: rect.minY) } - static func centerLeft(_ view: PView, keepTransform: Bool) -> CGPoint { + static func centerLeft(_ view: View, keepTransform: Bool) -> CGPoint { let rect = view.getRect(keepTransform: keepTransform) return CGPoint(x: rect.minX, y: rect.minY + (rect.height / 2)) } - static func center(_ view: PView, keepTransform: Bool) -> CGPoint { + static func center(_ view: View, keepTransform: Bool) -> CGPoint { let rect = view.getRect(keepTransform: keepTransform) return CGPoint(x: rect.minX + (rect.width / 2), y: rect.minY + (rect.height / 2)) } - static func centerRight(_ view: PView, keepTransform: Bool) -> CGPoint { + static func centerRight(_ view: View, keepTransform: Bool) -> CGPoint { let rect = view.getRect(keepTransform: keepTransform) return CGPoint(x: rect.minX + rect.width, y: rect.minY + (rect.height / 2)) } - static func bottomLeft(_ view: PView, keepTransform: Bool) -> CGPoint { + static func bottomLeft(_ view: View, keepTransform: Bool) -> CGPoint { let rect = view.getRect(keepTransform: keepTransform) return CGPoint(x: rect.minX, y: rect.minY + rect.height) } - static func bottomCenter(_ view: PView, keepTransform: Bool) -> CGPoint { + static func bottomCenter(_ view: View, keepTransform: Bool) -> CGPoint { let rect = view.getRect(keepTransform: keepTransform) return CGPoint(x: rect.minX + (rect.width / 2), y: rect.minY + rect.height) } - static func bottomRight(_ view: PView, keepTransform: Bool) -> CGPoint { + static func bottomRight(_ view: View, keepTransform: Bool) -> CGPoint { let rect = view.getRect(keepTransform: keepTransform) return CGPoint(x: rect.minX + rect.width, y: rect.minY + rect.height) } diff --git a/Sources/Impl/PinLayoutImpl+Coordinates.swift b/Sources/Impl/PinLayoutImpl+Coordinates.swift index 00edf3dd..f29d6a05 100644 --- a/Sources/Impl/PinLayoutImpl+Coordinates.swift +++ b/Sources/Impl/PinLayoutImpl+Coordinates.swift @@ -361,10 +361,10 @@ extension PinLayout { } } - fileprivate func computeCoordinates(_ point: CGPoint, _ layoutSuperview: PView, _ referenceSuperview: PView) -> CGPoint { + fileprivate func computeCoordinates(_ point: CGPoint, _ layoutSuperview: View, _ referenceSuperview: View) -> CGPoint { if layoutSuperview == referenceSuperview { return point // same superview => no coordinates conversion required. - } else if referenceSuperview == layoutSuperview.superview { + } else if referenceSuperview == layoutSuperview.superview as? View { let layoutSuperviewRect = layoutSuperview.getRect(keepTransform: keepTransform) return CGPoint(x: point.x - layoutSuperviewRect.origin.x, y: point.y - layoutSuperviewRect.origin.y) @@ -372,7 +372,7 @@ extension PinLayout { // coordinates, but UIView.convert(...) below use transformed coordinates! // Currently we only support 1 and 2 levels. } else { - return referenceSuperview.convert(point, to: layoutSuperview) + return referenceSuperview.convert(point, toView: layoutSuperview as! View.View) } } @@ -380,7 +380,7 @@ extension PinLayout { guard let layoutSuperview = layoutSuperview(context) else { return nil } var results: [CGPoint] = [] anchors.forEach({ (anchor) in - let anchor = anchor as! AnchorImpl + let anchor = anchor as! AnchorImpl if let referenceSuperview = referenceSuperview(anchor.view, context) { results.append(computeCoordinates(anchor.point(keepTransform: keepTransform), layoutSuperview, referenceSuperview)) @@ -396,7 +396,7 @@ extension PinLayout { } internal func computeCoordinate(forEdge edge: HorizontalEdge, _ context: Context) -> CGFloat? { - let edge = edge as! HorizontalEdgeImpl + let edge = edge as! HorizontalEdgeImpl guard let layoutSuperview = layoutSuperview(context) else { return nil } guard let referenceSuperview = referenceSuperview(edge.view, context) else { return nil } @@ -405,7 +405,7 @@ extension PinLayout { } internal func computeCoordinate(forEdge edge: VerticalEdge, _ context: Context) -> CGFloat? { - let edge = edge as! VerticalEdgeImpl + let edge = edge as! VerticalEdgeImpl guard let layoutSuperview = layoutSuperview(context) else { return nil } guard let referenceSuperview = referenceSuperview(edge.view, context) else { return nil } diff --git a/Sources/Impl/PinLayoutImpl+Layouting.swift b/Sources/Impl/PinLayoutImpl+Layouting.swift index 769fe61c..150b2789 100644 --- a/Sources/Impl/PinLayoutImpl+Layouting.swift +++ b/Sources/Impl/PinLayoutImpl+Layouting.swift @@ -35,7 +35,7 @@ extension PinLayout { isLayouted = true } - private func apply(onView view: PView) { + private func apply(onView view: View) { displayLayoutWarnings() var newRect = view.getRect(keepTransform: keepTransform) @@ -243,11 +243,7 @@ extension PinLayout { fitHeight = height } - #if os(iOS) || os(tvOS) let sizeThatFits = view.sizeThatFits(CGSize(width: fitWidth, height: fitHeight)) - #else - let sizeThatFits = view.intrinsicContentSize - #endif if fitWidth != .greatestFiniteMagnitude && (sizeThatFits.width > fitWidth) { size.width = fitWidth @@ -287,20 +283,7 @@ extension PinLayout { assertionFailure("Should not occured") } - #if os(iOS) || os(tvOS) let sizeThatFits = view.sizeThatFits(CGSize(width: fitWidth, height: fitHeight)) - #else - let sizeThatFits: CGSize - if #available(OSX 10.10, *) { - if let control = view as? NSControl { - sizeThatFits = control.sizeThatFits(CGSize(width: fitWidth, height: fitHeight)) - } else { - sizeThatFits = view.intrinsicContentSize - } - } else { - sizeThatFits = view.intrinsicContentSize - } - #endif if fitWidth != .greatestFiniteMagnitude { size.width = adjustSizeType.isFlexible ? sizeThatFits.width : fitWidth diff --git a/Sources/Impl/PinLayoutImpl+Relative.swift b/Sources/Impl/PinLayoutImpl+Relative.swift index d1fc19fb..98ff0d39 100644 --- a/Sources/Impl/PinLayoutImpl+Relative.swift +++ b/Sources/Impl/PinLayoutImpl+Relative.swift @@ -28,22 +28,22 @@ extension PinLayout { // // above(of ...) // - public func above(of relativeView: PView) -> PinLayout { + public func above(of relativeView: View) -> PinLayout { func context() -> String { return "above(of: \(relativeView))" } return above(relativeViews: [relativeView], aligned: nil, context: context) } - public func above(of relativeViews: [PView]) -> PinLayout { + public func above(of relativeViews: [View]) -> PinLayout { func context() -> String { return "above(of: \(relativeViews))" } return above(relativeViews: relativeViews, aligned: nil, context: context) } - public func above(of relativeView: PView, aligned: HorizontalAlign) -> PinLayout { + public func above(of relativeView: View, aligned: HorizontalAlign) -> PinLayout { func context() -> String { return "above(of: \(relativeView), aligned: \(aligned))" } return above(relativeViews: [relativeView], aligned: aligned, context: context) } - public func above(of relativeViews: [PView], aligned: HorizontalAlign) -> PinLayout { + public func above(of relativeViews: [View], aligned: HorizontalAlign) -> PinLayout { func context() -> String { return "above(of: \(relativeViews), aligned: \(aligned))" } return above(relativeViews: relativeViews, aligned: aligned, context: context) } @@ -51,22 +51,22 @@ extension PinLayout { // // below(of ...) // - public func below(of relativeView: PView) -> PinLayout { + public func below(of relativeView: View) -> PinLayout { func context() -> String { return "below(of: \(relativeView))" } return below(relativeViews: [relativeView], aligned: nil, context: context) } - public func below(of relativeViews: [PView]) -> PinLayout { + public func below(of relativeViews: [View]) -> PinLayout { func context() -> String { return "below(of: \(relativeViews))" } return below(relativeViews: relativeViews, aligned: nil, context: context) } - public func below(of relativeView: PView, aligned: HorizontalAlign) -> PinLayout { + public func below(of relativeView: View, aligned: HorizontalAlign) -> PinLayout { func context() -> String { return "below(of: \(relativeView), aligned: \(aligned))" } return below(relativeViews: [relativeView], aligned: aligned, context: context) } - public func below(of relativeViews: [PView], aligned: HorizontalAlign) -> PinLayout { + public func below(of relativeViews: [View], aligned: HorizontalAlign) -> PinLayout { func context() -> String { return "below(of: \(relativeViews), aligned: \(aligned))" } return below(relativeViews: relativeViews, aligned: aligned, context: context) } @@ -74,22 +74,22 @@ extension PinLayout { // // left(of ...) // - public func left(of relativeView: PView) -> PinLayout { + public func left(of relativeView: View) -> PinLayout { func context() -> String { return "left(of: \(relativeView))" } return left(relativeViews: [relativeView], aligned: nil, context: context) } - public func left(of relativeViews: [PView]) -> PinLayout { + public func left(of relativeViews: [View]) -> PinLayout { func context() -> String { return "left(of: \(relativeViews))" } return left(relativeViews: relativeViews, aligned: nil, context: context) } - public func left(of relativeView: PView, aligned: VerticalAlign) -> PinLayout { + public func left(of relativeView: View, aligned: VerticalAlign) -> PinLayout { func context() -> String { return "left(of: \(relativeView), aligned: \(aligned))" } return left(relativeViews: [relativeView], aligned: aligned, context: context) } - public func left(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout { + public func left(of relativeViews: [View], aligned: VerticalAlign) -> PinLayout { func context() -> String { return "left(of: \(relativeViews), aligned: \(aligned))" } return left(relativeViews: relativeViews, aligned: aligned, context: context) } @@ -97,27 +97,27 @@ extension PinLayout { // // right(of ...) // - public func right(of relativeView: PView) -> PinLayout { + public func right(of relativeView: View) -> PinLayout { func context() -> String { return "right(of: \(relativeView))" } return right(relativeViews: [relativeView], aligned: nil, context: context) } - public func right(of relativeViews: [PView]) -> PinLayout { + public func right(of relativeViews: [View]) -> PinLayout { func context() -> String { return "right(of: \(relativeViews))" } return right(relativeViews: relativeViews, aligned: nil, context: context) } - public func right(of relativeView: PView, aligned: VerticalAlign) -> PinLayout { + public func right(of relativeView: View, aligned: VerticalAlign) -> PinLayout { func context() -> String { return "right(of: \(relativeView), aligned: \(aligned))" } return right(relativeViews: [relativeView], aligned: aligned, context: context) } - public func right(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout { + public func right(of relativeViews: [View], aligned: VerticalAlign) -> PinLayout { func context() -> String { return "right(of: \(relativeViews), aligned: \(aligned))" } return right(relativeViews: relativeViews, aligned: aligned, context: context) } - public func before(of relativeView: PView) -> PinLayout { + public func before(of relativeView: View) -> PinLayout { func context() -> String { return "before(of: \(relativeView))" } if isLTR() { return left(relativeViews: [relativeView], aligned: nil, context: context) @@ -126,7 +126,7 @@ extension PinLayout { } } - public func before(of relativeViews: [PView]) -> PinLayout { + public func before(of relativeViews: [View]) -> PinLayout { func context() -> String { return "before(of: \(relativeViews))" } if isLTR() { return left(relativeViews: relativeViews, aligned: nil, context: context) @@ -135,7 +135,7 @@ extension PinLayout { } } - public func before(of relativeView: PView, aligned: VerticalAlign) -> PinLayout { + public func before(of relativeView: View, aligned: VerticalAlign) -> PinLayout { func context() -> String { return "before(of: \(relativeView), aligned: \(aligned))" } if isLTR() { return left(relativeViews: [relativeView], aligned: aligned, context: context) @@ -144,7 +144,7 @@ extension PinLayout { } } - public func before(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout { + public func before(of relativeViews: [View], aligned: VerticalAlign) -> PinLayout { func context() -> String { return "before(of: \(relativeViews), aligned: \(aligned))" } if isLTR() { return left(relativeViews: relativeViews, aligned: aligned, context: context) @@ -153,7 +153,7 @@ extension PinLayout { } } - public func after(of relativeView: PView) -> PinLayout { + public func after(of relativeView: View) -> PinLayout { func context() -> String { return "after(of: \(relativeView))" } if isLTR() { return right(relativeViews: [relativeView], aligned: nil, context: context) @@ -162,7 +162,7 @@ extension PinLayout { } } - public func after(of relativeViews: [PView]) -> PinLayout { + public func after(of relativeViews: [View]) -> PinLayout { func context() -> String { return "after(of: \(relativeViews))" } if isLTR() { return right(relativeViews: relativeViews, aligned: nil, context: context) @@ -171,7 +171,7 @@ extension PinLayout { } } - public func after(of relativeView: PView, aligned: VerticalAlign) -> PinLayout { + public func after(of relativeView: View, aligned: VerticalAlign) -> PinLayout { func context() -> String { return "after(of: \(relativeView))" } if isLTR() { return right(relativeViews: [relativeView], aligned: aligned, context: context) @@ -180,7 +180,7 @@ extension PinLayout { } } - public func after(of relativeViews: [PView], aligned: VerticalAlign) -> PinLayout { + public func after(of relativeViews: [View], aligned: VerticalAlign) -> PinLayout { func context() -> String { return "after(of: \(relativeViews), aligned: \(aligned))" } if isLTR() { return right(relativeViews: relativeViews, aligned: aligned, context: context) @@ -192,7 +192,7 @@ extension PinLayout { // MARK: fileprivate extension PinLayout { - fileprivate func above(relativeViews: [PView], aligned: HorizontalAlign?, context: Context) -> PinLayout { + fileprivate func above(relativeViews: [View], aligned: HorizontalAlign?, context: Context) -> PinLayout { guard let relativeViews = validateRelativeViews(relativeViews, context: context) else { return self } let anchors: [Anchor] @@ -215,7 +215,7 @@ extension PinLayout { return self } - fileprivate func below(relativeViews: [PView], aligned: HorizontalAlign?, context: Context) -> PinLayout { + fileprivate func below(relativeViews: [View], aligned: HorizontalAlign?, context: Context) -> PinLayout { guard let relativeViews = validateRelativeViews(relativeViews, context: context) else { return self } let anchors: [Anchor] @@ -238,7 +238,7 @@ extension PinLayout { return self } - fileprivate func left(relativeViews: [PView], aligned: VerticalAlign?, context: Context) -> PinLayout { + fileprivate func left(relativeViews: [View], aligned: VerticalAlign?, context: Context) -> PinLayout { guard let relativeViews = validateRelativeViews(relativeViews, context: context) else { return self } let anchors: [Anchor] @@ -259,7 +259,7 @@ extension PinLayout { return self } - fileprivate func right(relativeViews: [PView], aligned: VerticalAlign?, context: Context) -> PinLayout { + fileprivate func right(relativeViews: [View], aligned: VerticalAlign?, context: Context) -> PinLayout { guard let relativeViews = validateRelativeViews(relativeViews, context: context) else { return self } let anchors: [Anchor] @@ -355,7 +355,7 @@ extension PinLayout { return sum / CGFloat(list.count) } - fileprivate func validateRelativeViews(_ relativeViews: [PView], context: Context) -> [PView]? { + fileprivate func validateRelativeViews(_ relativeViews: [View], context: Context) -> [View]? { guard let _ = layoutSuperview(context) else { return nil } guard relativeViews.count > 0 else { warnWontBeApplied("At least one view must be visible (i.e. UIView.isHidden != true) ", context) diff --git a/Sources/Impl/PinLayoutImpl+Size.swift b/Sources/Impl/PinLayoutImpl+Size.swift index 94b83e6a..be6f7d62 100644 --- a/Sources/Impl/PinLayoutImpl+Size.swift +++ b/Sources/Impl/PinLayoutImpl+Size.swift @@ -80,7 +80,7 @@ extension PinLayout { return setSize(size, context) } - public func size(of view: PView) -> PinLayout { + public func size(of view: View) -> PinLayout { func context() -> String { return "size(of \(viewDescription(view)))" } return setSize(view.getRect(keepTransform: keepTransform).size, context) } @@ -90,7 +90,7 @@ extension PinLayout { return setAdjustSizeType(.aspectRatio(ratio), { "aspectRatio(\(ratio))" }) } - public func aspectRatio(of view: PView) -> PinLayout { + public func aspectRatio(of view: View) -> PinLayout { let rect = view.getRect(keepTransform: keepTransform) return setAdjustSizeType(.aspectRatio(rect.width / rect.height), { "aspectRatio(of: \(viewDescription(view)))" }) } diff --git a/Sources/Impl/PinLayoutImpl+Warning.swift b/Sources/Impl/PinLayoutImpl+Warning.swift index d8151fae..81f40696 100644 --- a/Sources/Impl/PinLayoutImpl+Warning.swift +++ b/Sources/Impl/PinLayoutImpl+Warning.swift @@ -36,17 +36,17 @@ extension PinLayout { } internal func relativeEdgeContext(method: String, edge: VerticalEdge) -> String { - let edge = edge as! VerticalEdgeImpl + let edge = edge as! VerticalEdgeImpl return "\(method)(to: .\(edge.type.rawValue), of: \(viewDescription(edge.view)))" } internal func relativeEdgeContext(method: String, edge: HorizontalEdge) -> String { - let edge = edge as! HorizontalEdgeImpl + let edge = edge as! HorizontalEdgeImpl return "\(method)(to: .\(edge.type.rawValue), of: \(viewDescription(edge.view))" } internal func relativeAnchorContext(method: String, anchor: Anchor) -> String { - let anchor = anchor as! AnchorImpl + let anchor = anchor as! AnchorImpl return "\(method)(to: .\(anchor.type.rawValue), of: \(viewDescription(anchor.view)))" } @@ -114,12 +114,12 @@ extension PinLayout { } } - internal func viewDescription(_ view: PView) -> String { + internal func viewDescription(_ view: View) -> String { let rect = view.getRect(keepTransform: keepTransform) return "(\(viewName(view)), Frame: \(rect))" } - internal func viewName(_ view: PView) -> String { + internal func viewName(_ view: View) -> String { return "\(type(of: view))" } @@ -127,7 +127,7 @@ extension PinLayout { return "UIEdgeInsets(top: \(insets.top), left: \(insets.left), bottom: \(insets.bottom), right: \(insets.right))" } - internal func pinLayoutDisplayConsoleWarning(_ text: String, _ view: PView) { + internal func pinLayoutDisplayConsoleWarning(_ text: String, _ view: View) { var displayText = "\n👉 \(text)" let rect = view.getRect(keepTransform: keepTransform) @@ -142,7 +142,7 @@ extension PinLayout { var hierarchy: [String] = [] while let parent = currentView.superview { hierarchy.insert("\(type(of: parent))", at: 0) - currentView = parent + currentView = parent as! View } if hierarchy.count > 0 { #if swift(>=4.1) @@ -152,7 +152,8 @@ extension PinLayout { #endif } - displayText += ", Tag: \(view.tag))\n" + // Removed, layoutable tag should probably not be exposed + //displayText += ", Tag: \(view.tag))\n" print(displayText) Pin.lastWarningText = text diff --git a/Sources/Impl/PinLayoutImpl.swift b/Sources/Impl/PinLayoutImpl.swift index 567f942b..b0c13bac 100644 --- a/Sources/Impl/PinLayoutImpl.swift +++ b/Sources/Impl/PinLayoutImpl.swift @@ -21,16 +21,14 @@ import Foundation #if os(iOS) || os(tvOS) import UIKit - public typealias PView = UIView public typealias PEdgeInsets = UIEdgeInsets #else import AppKit - public typealias PView = NSView public typealias PEdgeInsets = NSEdgeInsets #endif -public class PinLayout { - internal let view: PView +public class PinLayout { + internal let view: View internal let keepTransform: Bool internal var _top: CGFloat? // offset from superview's top edge @@ -70,7 +68,7 @@ public class PinLayout { internal var isLayouted = false - init(view: PView, keepTransform: Bool) { + init(view: View, keepTransform: Bool) { self.view = view self.keepTransform = keepTransform @@ -88,10 +86,14 @@ public class PinLayout { #if os(iOS) || os(tvOS) public var safeArea: PEdgeInsets { - if #available(iOS 11.0, tvOS 11.0, *) { - return view.safeAreaInsets + if let view = view as? UIView { + if #available(iOS 11.0, tvOS 11.0, *) { + return view.safeAreaInsets + } else { + return view.pinlayoutComputeSafeAreaInsets() + } } else { - return view.pinlayoutComputeSafeAreaInsets() + return PEdgeInsets.zero } } #endif @@ -642,7 +644,7 @@ public class PinLayout { return setWidth(percent.of(layoutSuperviewRect.width), context) } - public func width(of view: PView) -> PinLayout { + public func width(of view: View) -> PinLayout { let rect = view.getRect(keepTransform: keepTransform) return setWidth(rect.width, { return "width(of: \(viewDescription(view)))" }) } @@ -679,7 +681,7 @@ public class PinLayout { return setHeight(percent.of(layoutSuperviewRect.height), context) } - public func height(of view: PView) -> PinLayout { + public func height(of view: View) -> PinLayout { let rect = view.getRect(keepTransform: keepTransform) return setHeight(rect.height, { return "height(of: \(viewDescription(view)))" }) } @@ -936,9 +938,9 @@ extension PinLayout { } } - internal func layoutSuperview(_ context: Context) -> PView? { + internal func layoutSuperview(_ context: Context) -> View? { if let superview = view.superview { - return superview + return superview as? View } else { // Disable this warning: Using XIB, layoutSubview() is called even before views have been // added, and there is no way to modify that strange behaviour of UIKit. @@ -947,9 +949,9 @@ extension PinLayout { } } - internal func referenceSuperview(_ referenceView: PView, _ context: Context) -> PView? { + internal func referenceSuperview(_ referenceView: View, _ context: Context) -> View? { if let superview = referenceView.superview { - return superview + return superview as? View } else { warnWontBeApplied("the reference view \(viewDescription(referenceView)) must be added as a sub-view before being used as a reference.", context) return nil diff --git a/Sources/Impl/TypesImpl.swift b/Sources/Impl/TypesImpl.swift index 49d5f27e..4dbfa9cf 100644 --- a/Sources/Impl/TypesImpl.swift +++ b/Sources/Impl/TypesImpl.swift @@ -32,10 +32,10 @@ struct Size { var height: CGFloat? } -class EdgeListImpl: EdgeList { - internal let view: PView +class EdgeListImpl: EdgeList { + internal let view: View - init(view: PView) { + init(view: View) { self.view = view } @@ -52,14 +52,14 @@ class EdgeListImpl: EdgeList { var end: HorizontalEdge { return view.isLTR() ? right : left } } -class HorizontalEdgeImpl: HorizontalEdge { +class HorizontalEdgeImpl: HorizontalEdge { enum EdgeType: String { case left case hCenter case right } - let view: PView + let view: View let type: EdgeType func x(keepTransform: Bool) -> CGFloat { @@ -72,20 +72,20 @@ class HorizontalEdgeImpl: HorizontalEdge { } } - internal init(view: PView, type: EdgeType) { + internal init(view: View, type: EdgeType) { self.view = view self.type = type } } -class VerticalEdgeImpl: VerticalEdge { +class VerticalEdgeImpl: VerticalEdge { enum EdgeType: String { case top case vCenter case bottom } - internal let view: PView + internal let view: View internal let type: EdgeType func y(keepTransform: Bool) -> CGFloat { @@ -99,16 +99,16 @@ class VerticalEdgeImpl: VerticalEdge { } } - internal init(view: PView, type: EdgeType) { + internal init(view: View, type: EdgeType) { self.view = view self.type = type } } -class AnchorListImpl: AnchorList { - internal let view: PView +class AnchorListImpl: AnchorList { + internal let view: View - internal init(view: PView) { + internal init(view: View) { self.view = view } @@ -143,8 +143,8 @@ enum AnchorType: String { case bottomRight } -class AnchorImpl: Anchor { - let view: PView +class AnchorImpl: Anchor { + let view: View let type: AnchorType func point(keepTransform: Bool) -> CGPoint { @@ -161,7 +161,7 @@ class AnchorImpl: Anchor { } } - fileprivate init(view: PView, type: AnchorType) { + fileprivate init(view: View, type: AnchorType) { self.view = view self.type = type } diff --git a/Sources/Impl/View+LTR.swift b/Sources/Impl/View+LTR.swift index 4931f65a..18ddb53b 100644 --- a/Sources/Impl/View+LTR.swift +++ b/Sources/Impl/View+LTR.swift @@ -23,7 +23,7 @@ import Foundation import UIKit extension UIView { - func isLTR() -> Bool { + public func isLTR() -> Bool { switch Pin.layoutDirection { case .auto: if #available(iOS 9.0, *) { @@ -42,7 +42,7 @@ extension UIView { import AppKit extension NSView { - func isLTR() -> Bool { + public func isLTR() -> Bool { switch Pin.layoutDirection { case .auto: return self.userInterfaceLayoutDirection == .leftToRight case .ltr: return true diff --git a/Sources/Layoutable.swift b/Sources/Layoutable.swift new file mode 100644 index 00000000..cdb1434a --- /dev/null +++ b/Sources/Layoutable.swift @@ -0,0 +1,44 @@ +// +// Layoutable.swift +// PinLayout +// +// Created by Antoine Lamy on 2018-06-11. +// Copyright © 2018 mcswiftlayyout.mirego.com. All rights reserved. +// + +import Foundation + +public protocol Layoutable: AnyObject, Equatable { + associatedtype View: Layoutable + + var superview: View? { get } + var subviews: [View] { get } + + func getRect(keepTransform: Bool) -> CGRect + func setRect(_ rect: CGRect, keepTransform: Bool) + + func sizeThatFits(_ size: CGSize) -> CGSize + func sizeToFit() + + func convert(_ point: CGPoint, toView view: View) -> CGPoint + + func isLTR() -> Bool +} + +extension Layoutable { + public var pin: PinLayout { + return PinLayout(view: self as! Self.View, keepTransform: true) + } + + public var pinFrame: PinLayout { + return PinLayout(view: self as! Self.View, keepTransform: false) + } + + public var anchor: AnchorList { + return AnchorListImpl(view: self as! View) + } + + public var edge: EdgeList { + return EdgeListImpl(view: self as! View) + } +} diff --git a/Sources/NSView+PinLayout.swift b/Sources/NSView+PinLayout.swift index 59438fa2..683287d4 100644 --- a/Sources/NSView+PinLayout.swift +++ b/Sources/NSView+PinLayout.swift @@ -22,21 +22,19 @@ import Foundation #if os(macOS) import AppKit -public extension NSView { - public var pin: PinLayout { - return PinLayout(view: self, keepTransform: true) - } +extension NSView: Layoutable { + public typealias View = NSView - public var pinFrame: PinLayout { - return PinLayout(view: self, keepTransform: false) + public func convert(_ point: CGPoint, toView view: NSView) -> CGPoint { + return convert(point, to: view) } - public var anchor: AnchorList { - return AnchorListImpl(view: self) + public func sizeThatFits(_ size: CGSize) -> CGSize { + return CGSize.zero } - public var edge: EdgeList { - return EdgeListImpl(view: self) + public func sizeToFit() { + } // Expose PinLayout's objective-c interface. diff --git a/Sources/ObjectiveC/PinLayoutObjCImpl.swift b/Sources/ObjectiveC/PinLayoutObjCImpl.swift index 6fc96770..8e522294 100644 --- a/Sources/ObjectiveC/PinLayoutObjCImpl.swift +++ b/Sources/ObjectiveC/PinLayoutObjCImpl.swift @@ -24,10 +24,16 @@ import AppKit #endif @objc class PinLayoutObjCImpl: NSObject, PinLayoutObjC { - fileprivate var impl: PinLayout? + #if os(iOS) || os(tvOS) + typealias PView = UIView + #else + typealias PView = NSView + #endif + + fileprivate var impl: PinLayout? init(view: PView, keepTransform: Bool) { - impl = PinLayout(view: view, keepTransform: keepTransform) + impl = PinLayout(view: view, keepTransform: keepTransform) } deinit { diff --git a/Sources/UIView+PinLayout.swift b/Sources/UIView+PinLayout.swift index fb4b74f8..4a8d0db4 100644 --- a/Sources/UIView+PinLayout.swift +++ b/Sources/UIView+PinLayout.swift @@ -22,21 +22,11 @@ import Foundation #if os(iOS) || os(tvOS) import UIKit -public extension UIView { - public var pin: PinLayout { - return PinLayout(view: self, keepTransform: true) - } - - public var pinFrame: PinLayout { - return PinLayout(view: self, keepTransform: false) - } - - @objc public var anchor: AnchorList { - return AnchorListImpl(view: self) - } - - @objc public var edge: EdgeList { - return EdgeListImpl(view: self) +extension UIView: Layoutable { + public typealias View = UIView + + public func convert(_ point: CGPoint, toView view: UIView) -> CGPoint { + return convert(point, to: view) } // Expose PinLayout's objective-c interface. diff --git a/Sources/View+Rect.swift b/Sources/View+Rect.swift index ed09591a..29c7dfe9 100644 --- a/Sources/View+Rect.swift +++ b/Sources/View+Rect.swift @@ -12,7 +12,7 @@ import Foundation import UIKit extension UIView { - func getRect(keepTransform: Bool) -> CGRect { + public func getRect(keepTransform: Bool) -> CGRect { if keepTransform { /* To adjust the view's position and size, we don't set the UIView's frame directly, because we want to keep the @@ -31,8 +31,8 @@ extension UIView { } } - func setRect(_ rect: CGRect, keepTransform: Bool) { - let adjustedRect = Coordinates.adjustRectToDisplayScale(rect) + public func setRect(_ rect: CGRect, keepTransform: Bool) { + let adjustedRect = Coordinates.adjustRectToDisplayScale(rect) if keepTransform { /* @@ -57,7 +57,7 @@ extension UIView { import AppKit extension NSView { - func getRect(keepTransform: Bool) -> CGRect { + public func getRect(keepTransform: Bool) -> CGRect { if let superview = superview, !superview.isFlipped { var flippedRect = frame flippedRect.origin.y = superview.frame.height - flippedRect.height - flippedRect.origin.y @@ -67,8 +67,8 @@ extension NSView { } } - func setRect(_ rect: CGRect, keepTransform: Bool) { - let adjustedRect = Coordinates.adjustRectToDisplayScale(rect) + public func setRect(_ rect: CGRect, keepTransform: Bool) { + let adjustedRect = Coordinates.adjustRectToDisplayScale(rect) if let superview = superview, !superview.isFlipped { var flippedRect = adjustedRect diff --git a/Tests/BasicView.swift b/Tests/BasicView.swift index 261e7b92..f8aa3a22 100644 --- a/Tests/BasicView.swift +++ b/Tests/BasicView.swift @@ -53,10 +53,10 @@ class BasicView: PView { override func sizeThatFits(_ size: CGSize) -> CGSize { return _sizeThatFits(size) } - #else - func sizeThatFits(_ size: CGSize) -> CGSize { - return _sizeThatFits(size) - } +// #else +// @objc func sizeThatFits(_ size: CGSize) -> CGSize { +// return _sizeThatFits(size) +// } #endif fileprivate func _sizeThatFits(_ size: CGSize) -> CGSize { diff --git a/Tests/Common/AdjustSizeSpec.swift b/Tests/Common/AdjustSizeSpec.swift index 5f684c7b..98d34d36 100644 --- a/Tests/Common/AdjustSizeSpec.swift +++ b/Tests/Common/AdjustSizeSpec.swift @@ -45,7 +45,7 @@ class AdjustSizeSpec: QuickSpec { */ beforeSuite { - _pinlayoutSetUnitTest(displayScale: 2) + _pinlayoutSetUnitTest(scale: 2) } beforeEach { diff --git a/Tests/Common/AspectRatioTests.swift b/Tests/Common/AspectRatioTests.swift index 45ca9506..4c0f8553 100644 --- a/Tests/Common/AspectRatioTests.swift +++ b/Tests/Common/AspectRatioTests.swift @@ -41,7 +41,7 @@ class AspectRatioTests: QuickSpec { */ beforeSuite { - _pinlayoutSetUnitTest(displayScale: 2) + _pinlayoutSetUnitTest(scale: 2) } beforeEach { diff --git a/Tests/Common/JustifyAlignSpec.swift b/Tests/Common/JustifyAlignSpec.swift index 05b6ac53..1f4a29c5 100644 --- a/Tests/Common/JustifyAlignSpec.swift +++ b/Tests/Common/JustifyAlignSpec.swift @@ -34,7 +34,7 @@ class JustifyAlignSpec: QuickSpec { */ beforeSuite { - _pinlayoutSetUnitTest(displayScale: 2) + _pinlayoutSetUnitTest(scale: 2) } beforeEach { diff --git a/Tests/Common/LayoutMethodSpec.swift b/Tests/Common/LayoutMethodSpec.swift index a38fe2eb..9867aef1 100644 --- a/Tests/Common/LayoutMethodSpec.swift +++ b/Tests/Common/LayoutMethodSpec.swift @@ -34,7 +34,7 @@ class LayoutMethodSpec: QuickSpec { */ beforeSuite { - _pinlayoutSetUnitTest(displayScale: 2) + _pinlayoutSetUnitTest(scale: 2) } beforeEach { diff --git a/Tests/Common/MinMaxWidthHeightSpec.swift b/Tests/Common/MinMaxWidthHeightSpec.swift index 8b6c86df..83c863fe 100644 --- a/Tests/Common/MinMaxWidthHeightSpec.swift +++ b/Tests/Common/MinMaxWidthHeightSpec.swift @@ -34,7 +34,7 @@ class MinMaxWidthHeightSpec: QuickSpec { */ beforeSuite { - _pinlayoutSetUnitTest(displayScale: 2) + _pinlayoutSetUnitTest(scale: 2) } beforeEach { diff --git a/Tests/Common/WarningSpec.swift b/Tests/Common/WarningSpec.swift index aafecc55..92767598 100644 --- a/Tests/Common/WarningSpec.swift +++ b/Tests/Common/WarningSpec.swift @@ -34,7 +34,7 @@ class WarningSpec: QuickSpec { */ beforeSuite { - _pinlayoutSetUnitTest(displayScale: 2) + _pinlayoutSetUnitTest(scale: 2) } beforeEach { diff --git a/Tests/Common/WrapContentSpec.swift b/Tests/Common/WrapContentSpec.swift index ff56ae01..3dc44b49 100644 --- a/Tests/Common/WrapContentSpec.swift +++ b/Tests/Common/WrapContentSpec.swift @@ -41,7 +41,7 @@ class WrapContentSpec: QuickSpec { var aViewChild3: BasicView! beforeSuite { - _pinlayoutSetUnitTest(displayScale: 2) + _pinlayoutSetUnitTest(scale: 2) } beforeEach { From 8597168df21c8504ce5cca47059af1fb21acc103 Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Tue, 12 Jun 2018 19:28:58 -0400 Subject: [PATCH 03/11] Extract sizing in a separate SizeCalculable protocol --- PinLayout.xcodeproj/project.pbxproj | 16 +++++++++++++ Sources/Impl/PinLayoutImpl+Layouting.swift | 19 +++++++++++---- Sources/Impl/PinLayoutImpl+Size.swift | 1 + Sources/Layoutable+PinLayout.swift | 27 ++++++++++++++++++++++ Sources/Layoutable.swift | 21 ----------------- Sources/NSView+PinLayout.swift | 13 ++++------- Sources/ObjectiveC/PinLayoutObjC.swift | 1 + Sources/ObjectiveC/PinLayoutObjCImpl.swift | 1 + Sources/SizeCalculable.swift | 15 ++++++++++++ Sources/UIView+PinLayout.swift | 2 +- 10 files changed, 82 insertions(+), 34 deletions(-) create mode 100644 Sources/Layoutable+PinLayout.swift create mode 100644 Sources/SizeCalculable.swift diff --git a/PinLayout.xcodeproj/project.pbxproj b/PinLayout.xcodeproj/project.pbxproj index db7c4a1e..b27c9dcf 100644 --- a/PinLayout.xcodeproj/project.pbxproj +++ b/PinLayout.xcodeproj/project.pbxproj @@ -53,6 +53,12 @@ 24D18D241F3E37DD008129EF /* Pin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D231F3E37DD008129EF /* Pin.swift */; }; 24D18D261F3E5EA5008129EF /* Pin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D231F3E37DD008129EF /* Pin.swift */; }; 32A65F57D5D8D5204831FF3A /* Pods_PinLayoutTests_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 417E52FC81E208F91CF03C1D /* Pods_PinLayoutTests_iOS.framework */; }; + C80435D320D0891C00EB1BD7 /* SizeCalculable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C80435D220D0891C00EB1BD7 /* SizeCalculable.swift */; }; + C80435D520D0898000EB1BD7 /* Layoutable+PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = C80435D420D0898000EB1BD7 /* Layoutable+PinLayout.swift */; }; + C80435D620D08A2B00EB1BD7 /* SizeCalculable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C80435D220D0891C00EB1BD7 /* SizeCalculable.swift */; }; + C80435D720D08A2C00EB1BD7 /* SizeCalculable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C80435D220D0891C00EB1BD7 /* SizeCalculable.swift */; }; + C80435D820D08B7300EB1BD7 /* Layoutable+PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = C80435D420D0898000EB1BD7 /* Layoutable+PinLayout.swift */; }; + C80435D920D08B7400EB1BD7 /* Layoutable+PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = C80435D420D0898000EB1BD7 /* Layoutable+PinLayout.swift */; }; C82DC20C20CE9F6800B7ACF5 /* Layoutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82DC20B20CE9F6800B7ACF5 /* Layoutable.swift */; }; C82DC20D20CE9F6800B7ACF5 /* Layoutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82DC20B20CE9F6800B7ACF5 /* Layoutable.swift */; }; C82DC20E20CE9F6800B7ACF5 /* Layoutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82DC20B20CE9F6800B7ACF5 /* Layoutable.swift */; }; @@ -222,6 +228,8 @@ A02D58138C6BA063EB3E8E66 /* Pods-PinLayoutTests-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PinLayoutTests-iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-PinLayoutTests-iOS/Pods-PinLayoutTests-iOS.release.xcconfig"; sourceTree = ""; }; B7A69A7C17E9071CF457C39A /* Pods_PinLayoutTests_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PinLayoutTests_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BC74F9FA5B66BF5C299B7581 /* Pods-PinLayoutTests-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PinLayoutTests-macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PinLayoutTests-macOS/Pods-PinLayoutTests-macOS.debug.xcconfig"; sourceTree = ""; }; + C80435D220D0891C00EB1BD7 /* SizeCalculable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeCalculable.swift; sourceTree = ""; }; + C80435D420D0898000EB1BD7 /* Layoutable+PinLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Layoutable+PinLayout.swift"; sourceTree = ""; }; C82DC20B20CE9F6800B7ACF5 /* Layoutable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Layoutable.swift; sourceTree = ""; }; C8BDEE8FC7F6D6F36D69AE89 /* Pods-PinLayoutTests-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PinLayoutTests-iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PinLayoutTests-iOS/Pods-PinLayoutTests-iOS.debug.xcconfig"; sourceTree = ""; }; DF1A5CBA208106A900725EF5 /* UIView+PinLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+PinLayout.swift"; sourceTree = ""; }; @@ -360,6 +368,8 @@ 24D18D231F3E37DD008129EF /* Pin.swift */, DFF222CC20B999BD00AC2A84 /* Types.swift */, C82DC20B20CE9F6800B7ACF5 /* Layoutable.swift */, + C80435D220D0891C00EB1BD7 /* SizeCalculable.swift */, + C80435D420D0898000EB1BD7 /* Layoutable+PinLayout.swift */, DF1A5CBA208106A900725EF5 /* UIView+PinLayout.swift */, DF1A5CBC208106C900725EF5 /* NSView+PinLayout.swift */, DFA06B031E8B38B300B6D5E7 /* Impl */, @@ -836,6 +846,7 @@ 243C62041FC37F680082C327 /* PinLayoutImpl.swift in Sources */, 243C62071FC37F6C0082C327 /* PinLayoutImpl+Relative.swift in Sources */, DFF222CB20B9994300AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */, + C80435D720D08A2C00EB1BD7 /* SizeCalculable.swift in Sources */, 243B12BC1FC393580072A9C3 /* Percent.swift in Sources */, DFB3ECB72062A937005F226B /* PinSafeArea.swift in Sources */, DF96F30B20CB5DDD007CA714 /* View+Rect.swift in Sources */, @@ -848,6 +859,7 @@ 243C62091FC37F6C0082C327 /* Coordinates.swift in Sources */, 243C620A1FC37F6C0082C327 /* TypesImpl.swift in Sources */, 243C62061FC37F6C0082C327 /* PinLayoutImpl+Layouting.swift in Sources */, + C80435D920D08B7400EB1BD7 /* Layoutable+PinLayout.swift in Sources */, 243C62051FC37F6C0082C327 /* PinLayoutImpl+Coordinates.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -866,6 +878,7 @@ 2475B6C51FC37A900054CADD /* PinLayoutImpl+Layouting.swift in Sources */, DFF222C920B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */, 2475B6CF1FC37C570054CADD /* TypesImpl.swift in Sources */, + C80435D320D0891C00EB1BD7 /* SizeCalculable.swift in Sources */, 2475B6D11FC37C8C0054CADD /* View+LTR.swift in Sources */, DF96F30920CB5DB7007CA714 /* View+Rect.swift in Sources */, DFEAF71220C8081800E33147 /* PinLayoutImpl+Size.swift in Sources */, @@ -878,6 +891,7 @@ 241A277D1F8E958F00B1AD39 /* PinLayoutObjC.swift in Sources */, 24949A2E1EF69474003643D3 /* Filters.swift in Sources */, DFB3ECB12061602F005F226B /* PinSafeArea.swift in Sources */, + C80435D520D0898000EB1BD7 /* Layoutable+PinLayout.swift in Sources */, 2475B6CD1FC37C1C0054CADD /* PinLayoutImpl+Relative.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -950,6 +964,7 @@ DF1A5D422084CFD600725EF5 /* Percent.swift in Sources */, DF1A5D3E2084CFD600725EF5 /* PinLayoutImpl+Relative.swift in Sources */, DFF222CA20B9994200AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */, + C80435D620D08A2B00EB1BD7 /* SizeCalculable.swift in Sources */, DF1A5D442084CFD600725EF5 /* View+LTR.swift in Sources */, DF1A5D352084CFC100725EF5 /* NSView+PinLayout.swift in Sources */, DF96F30A20CB5DDC007CA714 /* View+Rect.swift in Sources */, @@ -962,6 +977,7 @@ DF1A5D3D2084CFD600725EF5 /* PinLayoutImpl+Layouting.swift in Sources */, DF1A5D3C2084CFD600725EF5 /* PinLayoutImpl+Coordinates.swift in Sources */, DF1A5D402084CFD600725EF5 /* PinSafeArea.swift in Sources */, + C80435D820D08B7300EB1BD7 /* Layoutable+PinLayout.swift in Sources */, DF1A5D432084CFD600725EF5 /* TypesImpl.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/Impl/PinLayoutImpl+Layouting.swift b/Sources/Impl/PinLayoutImpl+Layouting.swift index 150b2789..a79d7163 100644 --- a/Sources/Impl/PinLayoutImpl+Layouting.swift +++ b/Sources/Impl/PinLayoutImpl+Layouting.swift @@ -183,11 +183,11 @@ extension PinLayout { } } } - + private func computeSize() -> Size { var size = resolveSize() - if let adjustSizeType = adjustSizeType { + if #available(OSX 10.10, *), let adjustSizeType = adjustSizeType { switch adjustSizeType { case .fitTypeWidth, .fitTypeHeight, .fitTypeWidthFlexible, .fitTypeHeightFlexible: size = computeSizeToFit(adjustSizeType: adjustSizeType, size: size) @@ -226,7 +226,12 @@ extension PinLayout { return size } + @available(OSX 10.10, *) private func computeLegacyFitSize(size: Size) -> Size { + guard let sizeCalculableView = view as? SizeCalculable else { + warn("fitSize() won't be applied, view does not conform to protocol SizeCalculable.") + return size + } guard size.width != nil || size.height != nil else { warn("fitSize() won't be applied, neither the width nor the height can be determined.") return size @@ -243,7 +248,7 @@ extension PinLayout { fitHeight = height } - let sizeThatFits = view.sizeThatFits(CGSize(width: fitWidth, height: fitHeight)) + let sizeThatFits = sizeCalculableView.sizeThatFits(CGSize(width: fitWidth, height: fitHeight)) if fitWidth != .greatestFiniteMagnitude && (sizeThatFits.width > fitWidth) { size.width = fitWidth @@ -260,7 +265,13 @@ extension PinLayout { return size } + @available(OSX 10.10, *) private func computeSizeToFit(adjustSizeType: AdjustSizeType, size: Size) -> Size { + guard let sizeCalculableView = view as? SizeCalculable else { + warn("fitSize() won't be applied, view does not conform to protocol SizeCalculable.") + return size + } + var fitWidth = CGFloat.greatestFiniteMagnitude var fitHeight = CGFloat.greatestFiniteMagnitude var size = size @@ -283,7 +294,7 @@ extension PinLayout { assertionFailure("Should not occured") } - let sizeThatFits = view.sizeThatFits(CGSize(width: fitWidth, height: fitHeight)) + let sizeThatFits = sizeCalculableView.sizeThatFits(CGSize(width: fitWidth, height: fitHeight)) if fitWidth != .greatestFiniteMagnitude { size.width = adjustSizeType.isFlexible ? sizeThatFits.width : fitWidth diff --git a/Sources/Impl/PinLayoutImpl+Size.swift b/Sources/Impl/PinLayoutImpl+Size.swift index be6f7d62..c61a1b07 100644 --- a/Sources/Impl/PinLayoutImpl+Size.swift +++ b/Sources/Impl/PinLayoutImpl+Size.swift @@ -112,6 +112,7 @@ extension PinLayout { } #endif + @available(OSX 10.10, *) public func sizeToFit(_ fitType: FitType) -> PinLayout { return setAdjustSizeType(fitType.toAdjustSizeType(), { return "sizeToFit(\(fitType.description))" }) } diff --git a/Sources/Layoutable+PinLayout.swift b/Sources/Layoutable+PinLayout.swift new file mode 100644 index 00000000..a43b4642 --- /dev/null +++ b/Sources/Layoutable+PinLayout.swift @@ -0,0 +1,27 @@ +// +// Layoutable+PinLayout.swift +// PinLayout-iOS +// +// Created by Antoine Lamy on 2018-06-12. +// Copyright © 2018 mcswiftlayyout.mirego.com. All rights reserved. +// + +import Foundation + +extension Layoutable { + public var pin: PinLayout { + return PinLayout(view: self as! Self.View, keepTransform: true) + } + + public var pinFrame: PinLayout { + return PinLayout(view: self as! Self.View, keepTransform: false) + } + + public var anchor: AnchorList { + return AnchorListImpl(view: self as! View) + } + + public var edge: EdgeList { + return EdgeListImpl(view: self as! View) + } +} diff --git a/Sources/Layoutable.swift b/Sources/Layoutable.swift index cdb1434a..08fb5fe9 100644 --- a/Sources/Layoutable.swift +++ b/Sources/Layoutable.swift @@ -17,28 +17,7 @@ public protocol Layoutable: AnyObject, Equatable { func getRect(keepTransform: Bool) -> CGRect func setRect(_ rect: CGRect, keepTransform: Bool) - func sizeThatFits(_ size: CGSize) -> CGSize - func sizeToFit() - func convert(_ point: CGPoint, toView view: View) -> CGPoint func isLTR() -> Bool } - -extension Layoutable { - public var pin: PinLayout { - return PinLayout(view: self as! Self.View, keepTransform: true) - } - - public var pinFrame: PinLayout { - return PinLayout(view: self as! Self.View, keepTransform: false) - } - - public var anchor: AnchorList { - return AnchorListImpl(view: self as! View) - } - - public var edge: EdgeList { - return EdgeListImpl(view: self as! View) - } -} diff --git a/Sources/NSView+PinLayout.swift b/Sources/NSView+PinLayout.swift index 683287d4..43ec9688 100644 --- a/Sources/NSView+PinLayout.swift +++ b/Sources/NSView+PinLayout.swift @@ -29,18 +29,15 @@ extension NSView: Layoutable { return convert(point, to: view) } - public func sizeThatFits(_ size: CGSize) -> CGSize { - return CGSize.zero - } - - public func sizeToFit() { - - } - // Expose PinLayout's objective-c interface. @objc public var pinObjc: PinLayoutObjC { return PinLayoutObjCImpl(view: self, keepTransform: true) } } +@available(OSX 10.10, *) +extension NSControl: SizeCalculable { + +} + #endif diff --git a/Sources/ObjectiveC/PinLayoutObjC.swift b/Sources/ObjectiveC/PinLayoutObjC.swift index 0eb16a64..82b0be83 100644 --- a/Sources/ObjectiveC/PinLayoutObjC.swift +++ b/Sources/ObjectiveC/PinLayoutObjC.swift @@ -278,6 +278,7 @@ import AppKit @discardableResult func aspectRatio() -> PinLayoutObjC #endif + @available(OSX 10.10, *) @discardableResult func sizeToFit(_ fitType: Fit) -> PinLayoutObjC // diff --git a/Sources/ObjectiveC/PinLayoutObjCImpl.swift b/Sources/ObjectiveC/PinLayoutObjCImpl.swift index 8e522294..e7154ea7 100644 --- a/Sources/ObjectiveC/PinLayoutObjCImpl.swift +++ b/Sources/ObjectiveC/PinLayoutObjCImpl.swift @@ -621,6 +621,7 @@ import AppKit } #endif + @available(OSX 10.10, *) func sizeToFit(_ fitType: Fit) -> PinLayoutObjC { let type: FitType switch fitType { diff --git a/Sources/SizeCalculable.swift b/Sources/SizeCalculable.swift new file mode 100644 index 00000000..31fd2d08 --- /dev/null +++ b/Sources/SizeCalculable.swift @@ -0,0 +1,15 @@ +// +// Sizable.swift +// PinLayout-iOS +// +// Created by Antoine Lamy on 2018-06-12. +// Copyright © 2018 mcswiftlayyout.mirego.com. All rights reserved. +// + +import Foundation + +@available(OSX 10.10, *) +public protocol SizeCalculable { + func sizeThatFits(_ size: CGSize) -> CGSize + func sizeToFit() +} diff --git a/Sources/UIView+PinLayout.swift b/Sources/UIView+PinLayout.swift index 4a8d0db4..01a22ebe 100644 --- a/Sources/UIView+PinLayout.swift +++ b/Sources/UIView+PinLayout.swift @@ -22,7 +22,7 @@ import Foundation #if os(iOS) || os(tvOS) import UIKit -extension UIView: Layoutable { +extension UIView: Layoutable, SizeCalculable { public typealias View = UIView public func convert(_ point: CGPoint, toView view: UIView) -> CGPoint { From 369cfb89cbcf2950652513cc0ca6571b2ada7e7f Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Tue, 12 Jun 2018 19:44:38 -0400 Subject: [PATCH 04/11] Make test class conform to SizeCalculable --- Tests/BasicView.swift | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Tests/BasicView.swift b/Tests/BasicView.swift index f8aa3a22..4a8f2312 100644 --- a/Tests/BasicView.swift +++ b/Tests/BasicView.swift @@ -23,6 +23,8 @@ import UIKit import AppKit #endif +import PinLayout + class BasicView: PView { #if os(macOS) fileprivate var _isFlipped: Bool = true @@ -53,10 +55,6 @@ class BasicView: PView { override func sizeThatFits(_ size: CGSize) -> CGSize { return _sizeThatFits(size) } -// #else -// @objc func sizeThatFits(_ size: CGSize) -> CGSize { -// return _sizeThatFits(size) -// } #endif fileprivate func _sizeThatFits(_ size: CGSize) -> CGSize { @@ -75,3 +73,15 @@ class BasicView: PView { return newSize } } + +#if os(macOS) +extension BasicView: SizeCalculable { + func sizeThatFits(_ size: CGSize) -> CGSize { + return _sizeThatFits(size) + } + + func sizeToFit() { + // Do nothing + } +} +#endif From 3a2c48fd983f7ae2c971c16f7176b9ec4c727235 Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Wed, 13 Jun 2018 08:06:07 -0400 Subject: [PATCH 05/11] Move functions alongside protocol conformance declaration --- PinLayout.xcodeproj/project.pbxproj | 16 ------ Sources/Impl/View+LTR.swift | 53 ------------------- Sources/NSView+PinLayout.swift | 30 +++++++++++ Sources/UIView+PinLayout.swift | 57 +++++++++++++++++++- Sources/View+Rect.swift | 82 ----------------------------- 5 files changed, 86 insertions(+), 152 deletions(-) delete mode 100644 Sources/Impl/View+LTR.swift delete mode 100644 Sources/View+Rect.swift diff --git a/PinLayout.xcodeproj/project.pbxproj b/PinLayout.xcodeproj/project.pbxproj index b27c9dcf..b249a2db 100644 --- a/PinLayout.xcodeproj/project.pbxproj +++ b/PinLayout.xcodeproj/project.pbxproj @@ -23,7 +23,6 @@ 243C62081FC37F6C0082C327 /* PinLayoutImpl+Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6C81FC37C1C0054CADD /* PinLayoutImpl+Warning.swift */; }; 243C62091FC37F6C0082C327 /* Coordinates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6D21FC37CD40054CADD /* Coordinates.swift */; }; 243C620A1FC37F6C0082C327 /* TypesImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6CE1FC37C570054CADD /* TypesImpl.swift */; }; - 243C620B1FC37F6C0082C327 /* View+LTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6D01FC37C8C0054CADD /* View+LTR.swift */; }; 243C620C1FC37FA30082C327 /* PinLayoutTVOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 2475B6D71FC37D4D0054CADD /* PinLayoutTVOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 243C620F1FC3834B0082C327 /* Percent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 243C620E1FC3834B0082C327 /* Percent.swift */; }; 244C6E151E776A0C0074FC74 /* MarginsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 244C6E141E776A0C0074FC74 /* MarginsSpec.swift */; }; @@ -39,7 +38,6 @@ 2475B6CC1FC37C1C0054CADD /* PinLayoutImpl+Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6C81FC37C1C0054CADD /* PinLayoutImpl+Warning.swift */; }; 2475B6CD1FC37C1C0054CADD /* PinLayoutImpl+Relative.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6C91FC37C1C0054CADD /* PinLayoutImpl+Relative.swift */; }; 2475B6CF1FC37C570054CADD /* TypesImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6CE1FC37C570054CADD /* TypesImpl.swift */; }; - 2475B6D11FC37C8C0054CADD /* View+LTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6D01FC37C8C0054CADD /* View+LTR.swift */; }; 2475B6D31FC37CD40054CADD /* Coordinates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6D21FC37CD40054CADD /* Coordinates.swift */; }; 2475B6DB1FC37D4D0054CADD /* PinLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 2475B6D91FC37D4D0054CADD /* PinLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2482908C1E78CFFC00667D08 /* RelativePositionSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2482908B1E78CFFC00667D08 /* RelativePositionSpec.swift */; }; @@ -81,16 +79,12 @@ DF1A5D412084CFD600725EF5 /* Coordinates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6D21FC37CD40054CADD /* Coordinates.swift */; }; DF1A5D422084CFD600725EF5 /* Percent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 243C620E1FC3834B0082C327 /* Percent.swift */; }; DF1A5D432084CFD600725EF5 /* TypesImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6CE1FC37C570054CADD /* TypesImpl.swift */; }; - DF1A5D442084CFD600725EF5 /* View+LTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6D01FC37C8C0054CADD /* View+LTR.swift */; }; DF1E39B520482B200002D0AA /* PinSafeAreaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1E39B420482B1F0002D0AA /* PinSafeAreaTests.swift */; }; DF28022420C2B13800A1833B /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222CC20B999BD00AC2A84 /* Types.swift */; }; DF28022520C2B13900A1833B /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222CC20B999BD00AC2A84 /* Types.swift */; }; DF28022620C2B15A00A1833B /* Types+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222CE20B99A6600AC2A84 /* Types+Description.swift */; }; DF28022720C2B15B00A1833B /* Types+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF222CE20B99A6600AC2A84 /* Types+Description.swift */; }; DF7A36BD1E918301000F9856 /* PinEdgesSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF7A36BC1E918301000F9856 /* PinEdgesSpec.swift */; }; - DF96F30920CB5DB7007CA714 /* View+Rect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF96F30820CB5DB7007CA714 /* View+Rect.swift */; }; - DF96F30A20CB5DDC007CA714 /* View+Rect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF96F30820CB5DB7007CA714 /* View+Rect.swift */; }; - DF96F30B20CB5DDD007CA714 /* View+Rect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF96F30820CB5DB7007CA714 /* View+Rect.swift */; }; DF96F30E20CB6362007CA714 /* PinLayoutObjCImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 241A277C1F8E958F00B1AD39 /* PinLayoutObjCImpl.swift */; }; DFABC01F208781A900CB6494 /* Types+Appkit.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFABC01E208781A900CB6494 /* Types+Appkit.swift */; }; DFABC022208781ED00CB6494 /* Types+UIKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFABC020208781C700CB6494 /* Types+UIKit.swift */; }; @@ -206,7 +200,6 @@ 2475B6C81FC37C1C0054CADD /* PinLayoutImpl+Warning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "PinLayoutImpl+Warning.swift"; path = "Impl/PinLayoutImpl+Warning.swift"; sourceTree = ""; }; 2475B6C91FC37C1C0054CADD /* PinLayoutImpl+Relative.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "PinLayoutImpl+Relative.swift"; path = "Impl/PinLayoutImpl+Relative.swift"; sourceTree = ""; }; 2475B6CE1FC37C570054CADD /* TypesImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TypesImpl.swift; path = Impl/TypesImpl.swift; sourceTree = ""; }; - 2475B6D01FC37C8C0054CADD /* View+LTR.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "View+LTR.swift"; path = "Impl/View+LTR.swift"; sourceTree = ""; }; 2475B6D21FC37CD40054CADD /* Coordinates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Coordinates.swift; path = Impl/Coordinates.swift; sourceTree = ""; }; 2475B6D61FC37D4D0054CADD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 2475B6D71FC37D4D0054CADD /* PinLayoutTVOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PinLayoutTVOS.h; sourceTree = ""; }; @@ -240,7 +233,6 @@ DF1A5D2E2084CF9700725EF5 /* PinLayoutMacOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PinLayoutMacOS.h; sourceTree = ""; }; DF1E39B420482B1F0002D0AA /* PinSafeAreaTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PinSafeAreaTests.swift; sourceTree = ""; }; DF7A36BC1E918301000F9856 /* PinEdgesSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PinEdgesSpec.swift; sourceTree = ""; }; - DF96F30820CB5DB7007CA714 /* View+Rect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Rect.swift"; sourceTree = ""; }; DFABC01E208781A900CB6494 /* Types+Appkit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Types+Appkit.swift"; sourceTree = ""; }; DFABC020208781C700CB6494 /* Types+UIKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Types+UIKit.swift"; sourceTree = ""; }; DFB3ECB02061602E005F226B /* PinSafeArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PinSafeArea.swift; path = Impl/PinSafeArea.swift; sourceTree = ""; }; @@ -429,8 +421,6 @@ 243C620E1FC3834B0082C327 /* Percent.swift */, 2475B6CE1FC37C570054CADD /* TypesImpl.swift */, DFF222CE20B99A6600AC2A84 /* Types+Description.swift */, - 2475B6D01FC37C8C0054CADD /* View+LTR.swift */, - DF96F30820CB5DB7007CA714 /* View+Rect.swift */, ); name = Impl; sourceTree = ""; @@ -849,13 +839,11 @@ C80435D720D08A2C00EB1BD7 /* SizeCalculable.swift in Sources */, 243B12BC1FC393580072A9C3 /* Percent.swift in Sources */, DFB3ECB72062A937005F226B /* PinSafeArea.swift in Sources */, - DF96F30B20CB5DDD007CA714 /* View+Rect.swift in Sources */, C82DC20E20CE9F6800B7ACF5 /* Layoutable.swift in Sources */, DFEAF75420C9667D00E33147 /* PinLayoutImpl+Size.swift in Sources */, DF1A5D0420812DE100725EF5 /* UIView+PinLayout.swift in Sources */, 24B02B091F2A713000C18179 /* Filters.swift in Sources */, 24B02B0A1F2A713300C18179 /* PinLayout.swift in Sources */, - 243C620B1FC37F6C0082C327 /* View+LTR.swift in Sources */, 243C62091FC37F6C0082C327 /* Coordinates.swift in Sources */, 243C620A1FC37F6C0082C327 /* TypesImpl.swift in Sources */, 243C62061FC37F6C0082C327 /* PinLayoutImpl+Layouting.swift in Sources */, @@ -879,8 +867,6 @@ DFF222C920B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */, 2475B6CF1FC37C570054CADD /* TypesImpl.swift in Sources */, C80435D320D0891C00EB1BD7 /* SizeCalculable.swift in Sources */, - 2475B6D11FC37C8C0054CADD /* View+LTR.swift in Sources */, - DF96F30920CB5DB7007CA714 /* View+Rect.swift in Sources */, DFEAF71220C8081800E33147 /* PinLayoutImpl+Size.swift in Sources */, C82DC20C20CE9F6800B7ACF5 /* Layoutable.swift in Sources */, DF96F30E20CB6362007CA714 /* PinLayoutObjCImpl.swift in Sources */, @@ -965,9 +951,7 @@ DF1A5D3E2084CFD600725EF5 /* PinLayoutImpl+Relative.swift in Sources */, DFF222CA20B9994200AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */, C80435D620D08A2B00EB1BD7 /* SizeCalculable.swift in Sources */, - DF1A5D442084CFD600725EF5 /* View+LTR.swift in Sources */, DF1A5D352084CFC100725EF5 /* NSView+PinLayout.swift in Sources */, - DF96F30A20CB5DDC007CA714 /* View+Rect.swift in Sources */, C82DC20D20CE9F6800B7ACF5 /* Layoutable.swift in Sources */, DFEAF75320C9667C00E33147 /* PinLayoutImpl+Size.swift in Sources */, DF1A5D3A2084CFC600725EF5 /* UIView+PinLayout.swift in Sources */, diff --git a/Sources/Impl/View+LTR.swift b/Sources/Impl/View+LTR.swift deleted file mode 100644 index 18ddb53b..00000000 --- a/Sources/Impl/View+LTR.swift +++ /dev/null @@ -1,53 +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. - -import Foundation - -#if os(iOS) || os(tvOS) -import UIKit - -extension UIView { - public func isLTR() -> Bool { - switch Pin.layoutDirection { - case .auto: - if #available(iOS 9.0, *) { - return UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .leftToRight - } else if let shared = UIApplication.value(forKey: "sharedApplication") as? UIApplication { - return shared.userInterfaceLayoutDirection == .leftToRight - } else { - return true - } - case .ltr: return true - case .rtl: return false - } - } -} -#else -import AppKit - -extension NSView { - public func isLTR() -> Bool { - switch Pin.layoutDirection { - case .auto: return self.userInterfaceLayoutDirection == .leftToRight - case .ltr: return true - case .rtl: return false - } - } -} -#endif diff --git a/Sources/NSView+PinLayout.swift b/Sources/NSView+PinLayout.swift index 43ec9688..9f9d1098 100644 --- a/Sources/NSView+PinLayout.swift +++ b/Sources/NSView+PinLayout.swift @@ -25,10 +25,40 @@ import AppKit extension NSView: Layoutable { public typealias View = NSView + public func getRect(keepTransform: Bool) -> CGRect { + if let superview = superview, !superview.isFlipped { + var flippedRect = frame + flippedRect.origin.y = superview.frame.height - flippedRect.height - flippedRect.origin.y + return flippedRect + } else { + return frame + } + } + + public func setRect(_ rect: CGRect, keepTransform: Bool) { + let adjustedRect = Coordinates.adjustRectToDisplayScale(rect) + + if let superview = superview, !superview.isFlipped { + var flippedRect = adjustedRect + flippedRect.origin.y = superview.frame.height - flippedRect.height - flippedRect.origin.y + frame = flippedRect + } else { + frame = adjustedRect + } + } + public func convert(_ point: CGPoint, toView view: NSView) -> CGPoint { return convert(point, to: view) } + public func isLTR() -> Bool { + switch Pin.layoutDirection { + case .auto: return self.userInterfaceLayoutDirection == .leftToRight + case .ltr: return true + case .rtl: return false + } + } + // Expose PinLayout's objective-c interface. @objc public var pinObjc: PinLayoutObjC { return PinLayoutObjCImpl(view: self, keepTransform: true) diff --git a/Sources/UIView+PinLayout.swift b/Sources/UIView+PinLayout.swift index 01a22ebe..1c8b7d83 100644 --- a/Sources/UIView+PinLayout.swift +++ b/Sources/UIView+PinLayout.swift @@ -24,11 +24,66 @@ import UIKit extension UIView: Layoutable, SizeCalculable { public typealias View = UIView - + + public func getRect(keepTransform: Bool) -> CGRect { + if keepTransform { + /* + To adjust the view's position and size, we don't set the UIView's frame directly, because we want to keep the + view's transform (UIView.transform). + By setting the view's center and bounds we really set the frame of the non-transformed view, and this keep + the view's transform. So view's transforms won't be affected/altered by PinLayout. + */ + let size = bounds.size + // See setRect(...) for details about this calculation. + let origin = CGPoint(x: center.x - (size.width * layer.anchorPoint.x), + y: center.y - (size.height * layer.anchorPoint.y)) + + return CGRect(origin: origin, size: size) + } else { + return frame + } + } + + public func setRect(_ rect: CGRect, keepTransform: Bool) { + let adjustedRect = Coordinates.adjustRectToDisplayScale(rect) + + if keepTransform { + /* + To adjust the view's position and size, we don't set the UIView's frame directly, because we want to keep the + view's transform (UIView.transform). + By setting the view's center and bounds we really set the frame of the non-transformed view, and this keep + the view's transform. So view's transforms won't be affected/altered by PinLayout. + */ + + // NOTE: The center is offset by the layer.anchorPoint, so we have to take it into account. + center = CGPoint(x: adjustedRect.origin.x + (adjustedRect.width * layer.anchorPoint.x), + y: adjustedRect.origin.y + (adjustedRect.height * layer.anchorPoint.y)) + // NOTE: We must set only the bounds's size and keep the origin. + bounds.size = adjustedRect.size + } else { + frame = adjustedRect + } + } + public func convert(_ point: CGPoint, toView view: UIView) -> CGPoint { return convert(point, to: view) } + public func isLTR() -> Bool { + switch Pin.layoutDirection { + case .auto: + if #available(iOS 9.0, *) { + return UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .leftToRight + } else if let shared = UIApplication.value(forKey: "sharedApplication") as? UIApplication { + return shared.userInterfaceLayoutDirection == .leftToRight + } else { + return true + } + case .ltr: return true + case .rtl: return false + } + } + // Expose PinLayout's objective-c interface. @objc public var pinObjc: PinLayoutObjC { return PinLayoutObjCImpl(view: self, keepTransform: true) diff --git a/Sources/View+Rect.swift b/Sources/View+Rect.swift deleted file mode 100644 index 29c7dfe9..00000000 --- a/Sources/View+Rect.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// View+Rect.swift -// PinLayout-iOS -// -// Created by Luc Dion on 2018-06-08. -// Copyright © 2018 mcswiftlayyout.mirego.com. All rights reserved. -// - -import Foundation - -#if os(iOS) || os(tvOS) -import UIKit - -extension UIView { - public func getRect(keepTransform: Bool) -> CGRect { - if keepTransform { - /* - To adjust the view's position and size, we don't set the UIView's frame directly, because we want to keep the - view's transform (UIView.transform). - By setting the view's center and bounds we really set the frame of the non-transformed view, and this keep - the view's transform. So view's transforms won't be affected/altered by PinLayout. - */ - let size = bounds.size - // See setRect(...) for details about this calculation. - let origin = CGPoint(x: center.x - (size.width * layer.anchorPoint.x), - y: center.y - (size.height * layer.anchorPoint.y)) - - return CGRect(origin: origin, size: size) - } else { - return frame - } - } - - public func setRect(_ rect: CGRect, keepTransform: Bool) { - let adjustedRect = Coordinates.adjustRectToDisplayScale(rect) - - if keepTransform { - /* - To adjust the view's position and size, we don't set the UIView's frame directly, because we want to keep the - view's transform (UIView.transform). - By setting the view's center and bounds we really set the frame of the non-transformed view, and this keep - the view's transform. So view's transforms won't be affected/altered by PinLayout. - */ - - // NOTE: The center is offset by the layer.anchorPoint, so we have to take it into account. - center = CGPoint(x: adjustedRect.origin.x + (adjustedRect.width * layer.anchorPoint.x), - y: adjustedRect.origin.y + (adjustedRect.height * layer.anchorPoint.y)) - // NOTE: We must set only the bounds's size and keep the origin. - bounds.size = adjustedRect.size - } else { - frame = adjustedRect - } - } -} -#else - -import AppKit - -extension NSView { - public func getRect(keepTransform: Bool) -> CGRect { - if let superview = superview, !superview.isFlipped { - var flippedRect = frame - flippedRect.origin.y = superview.frame.height - flippedRect.height - flippedRect.origin.y - return flippedRect - } else { - return frame - } - } - - public func setRect(_ rect: CGRect, keepTransform: Bool) { - let adjustedRect = Coordinates.adjustRectToDisplayScale(rect) - - if let superview = superview, !superview.isFlipped { - var flippedRect = adjustedRect - flippedRect.origin.y = superview.frame.height - flippedRect.height - flippedRect.origin.y - frame = flippedRect - } else { - frame = adjustedRect - } - } -} -#endif From addad7d149b3403c6913ae8166acc1b6fbc5b12c Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Wed, 13 Jun 2018 09:23:32 -0400 Subject: [PATCH 06/11] Code review comments --- Sources/Impl/PinLayoutImpl+Coordinates.swift | 2 +- Sources/Impl/PinLayoutImpl+Warning.swift | 3 +-- Sources/Layoutable.swift | 4 ++-- Sources/NSView+PinLayout.swift | 4 ---- Sources/SizeCalculable.swift | 1 - Sources/UIView+PinLayout.swift | 4 ---- 6 files changed, 4 insertions(+), 14 deletions(-) diff --git a/Sources/Impl/PinLayoutImpl+Coordinates.swift b/Sources/Impl/PinLayoutImpl+Coordinates.swift index f29d6a05..4e40c787 100644 --- a/Sources/Impl/PinLayoutImpl+Coordinates.swift +++ b/Sources/Impl/PinLayoutImpl+Coordinates.swift @@ -372,7 +372,7 @@ extension PinLayout { // coordinates, but UIView.convert(...) below use transformed coordinates! // Currently we only support 1 and 2 levels. } else { - return referenceSuperview.convert(point, toView: layoutSuperview as! View.View) + return referenceSuperview.convert(point, to: layoutSuperview as? View.View) } } diff --git a/Sources/Impl/PinLayoutImpl+Warning.swift b/Sources/Impl/PinLayoutImpl+Warning.swift index 81f40696..ef9fddca 100644 --- a/Sources/Impl/PinLayoutImpl+Warning.swift +++ b/Sources/Impl/PinLayoutImpl+Warning.swift @@ -152,8 +152,7 @@ extension PinLayout { #endif } - // Removed, layoutable tag should probably not be exposed - //displayText += ", Tag: \(view.tag))\n" + displayText += ", Debug description: \(view.debugDescription))\n" print(displayText) Pin.lastWarningText = text diff --git a/Sources/Layoutable.swift b/Sources/Layoutable.swift index 08fb5fe9..835e1ea3 100644 --- a/Sources/Layoutable.swift +++ b/Sources/Layoutable.swift @@ -8,7 +8,7 @@ import Foundation -public protocol Layoutable: AnyObject, Equatable { +public protocol Layoutable: AnyObject, Equatable, CustomDebugStringConvertible { associatedtype View: Layoutable var superview: View? { get } @@ -17,7 +17,7 @@ public protocol Layoutable: AnyObject, Equatable { func getRect(keepTransform: Bool) -> CGRect func setRect(_ rect: CGRect, keepTransform: Bool) - func convert(_ point: CGPoint, toView view: View) -> CGPoint + func convert(_ point: CGPoint, to view: View?) -> CGPoint func isLTR() -> Bool } diff --git a/Sources/NSView+PinLayout.swift b/Sources/NSView+PinLayout.swift index 9f9d1098..e31ba8cc 100644 --- a/Sources/NSView+PinLayout.swift +++ b/Sources/NSView+PinLayout.swift @@ -47,10 +47,6 @@ extension NSView: Layoutable { } } - public func convert(_ point: CGPoint, toView view: NSView) -> CGPoint { - return convert(point, to: view) - } - public func isLTR() -> Bool { switch Pin.layoutDirection { case .auto: return self.userInterfaceLayoutDirection == .leftToRight diff --git a/Sources/SizeCalculable.swift b/Sources/SizeCalculable.swift index 31fd2d08..36d1b89e 100644 --- a/Sources/SizeCalculable.swift +++ b/Sources/SizeCalculable.swift @@ -8,7 +8,6 @@ import Foundation -@available(OSX 10.10, *) public protocol SizeCalculable { func sizeThatFits(_ size: CGSize) -> CGSize func sizeToFit() diff --git a/Sources/UIView+PinLayout.swift b/Sources/UIView+PinLayout.swift index 1c8b7d83..35bc2ab9 100644 --- a/Sources/UIView+PinLayout.swift +++ b/Sources/UIView+PinLayout.swift @@ -65,10 +65,6 @@ extension UIView: Layoutable, SizeCalculable { } } - public func convert(_ point: CGPoint, toView view: UIView) -> CGPoint { - return convert(point, to: view) - } - public func isLTR() -> Bool { switch Pin.layoutDirection { case .auto: From e0556761aee175c05d52946b85e33774a39d461b Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Wed, 13 Jun 2018 09:23:41 -0400 Subject: [PATCH 07/11] Fix ObjC support --- Sources/ObjectiveC/PinLayoutObjCImpl.swift | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Sources/ObjectiveC/PinLayoutObjCImpl.swift b/Sources/ObjectiveC/PinLayoutObjCImpl.swift index e7154ea7..b6ffd878 100644 --- a/Sources/ObjectiveC/PinLayoutObjCImpl.swift +++ b/Sources/ObjectiveC/PinLayoutObjCImpl.swift @@ -23,6 +23,28 @@ import UIKit import AppKit #endif +#if os(iOS) || os(tvOS) +@objc extension UIView { + public var anchor: AnchorList { + return AnchorListImpl(view: self) + } + + public var edge: EdgeList { + return EdgeListImpl(view: self) + } +} +#else +@objc extension NSView { + public var anchor: AnchorList { + return AnchorListImpl(view: self) + } + + public var edge: EdgeList { + return EdgeListImpl(view: self) + } +} +#endif + @objc class PinLayoutObjCImpl: NSObject, PinLayoutObjC { #if os(iOS) || os(tvOS) typealias PView = UIView From 7ddb2bb0c7b8dd9b8005254c74c42cfc4b2ebe7a Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Wed, 13 Jun 2018 18:32:34 -0400 Subject: [PATCH 08/11] Check for SizeCalculable before assigning adjustSizeType --- Sources/Impl/PinLayoutImpl+Layouting.swift | 4 ++-- Sources/Impl/PinLayoutImpl+Size.swift | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Sources/Impl/PinLayoutImpl+Layouting.swift b/Sources/Impl/PinLayoutImpl+Layouting.swift index a79d7163..8a8995e3 100644 --- a/Sources/Impl/PinLayoutImpl+Layouting.swift +++ b/Sources/Impl/PinLayoutImpl+Layouting.swift @@ -229,7 +229,7 @@ extension PinLayout { @available(OSX 10.10, *) private func computeLegacyFitSize(size: Size) -> Size { guard let sizeCalculableView = view as? SizeCalculable else { - warn("fitSize() won't be applied, view does not conform to protocol SizeCalculable.") + assertionFailure("Should not occurs, protocol conformance is checked before assigning adjustSizeType") return size } guard size.width != nil || size.height != nil else { @@ -268,7 +268,7 @@ extension PinLayout { @available(OSX 10.10, *) private func computeSizeToFit(adjustSizeType: AdjustSizeType, size: Size) -> Size { guard let sizeCalculableView = view as? SizeCalculable else { - warn("fitSize() won't be applied, view does not conform to protocol SizeCalculable.") + assertionFailure("Should not occurs, protocol conformance is checked before assigning adjustSizeType") return size } diff --git a/Sources/Impl/PinLayoutImpl+Size.swift b/Sources/Impl/PinLayoutImpl+Size.swift index c61a1b07..c5bc4486 100644 --- a/Sources/Impl/PinLayoutImpl+Size.swift +++ b/Sources/Impl/PinLayoutImpl+Size.swift @@ -42,6 +42,15 @@ enum AdjustSizeType { } } + internal var requiresSizeCalculable: Bool { + switch self { + case .fitTypeWidth, .fitTypeHeight, .fitTypeWidthFlexible, .fitTypeHeightFlexible, .fitSizeLegacy: + return true + case .aspectRatio(_): + return false + } + } + func toFitType() -> FitType? { switch self { case .fitTypeWidth: return .width @@ -139,9 +148,14 @@ extension PinLayout { return self } - if let type = type, case let AdjustSizeType.aspectRatio(ratio) = type, ratio <= 0 { - warnWontBeApplied("the aspectRatio (\(ratio)) must be greater than zero.", context) - return self + if let type = type { + if case let AdjustSizeType.aspectRatio(ratio) = type, ratio <= 0 { + warnWontBeApplied("the aspectRatio (\(ratio)) must be greater than zero.", context) + return self + } else if type.requiresSizeCalculable, !(view is SizeCalculable) { + warnWontBeApplied("the view must conform to protocol SizeCalculable for it's size to be computed.", context) + return self + } } adjustSizeType = type From 46c7d9468a17f11fa39f5ba18c5f016ffaef7359 Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Thu, 14 Jun 2018 08:41:20 -0400 Subject: [PATCH 09/11] Add missing imports --- Sources/Layoutable.swift | 6 +++++- Sources/SizeCalculable.swift | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Sources/Layoutable.swift b/Sources/Layoutable.swift index 835e1ea3..398c8feb 100644 --- a/Sources/Layoutable.swift +++ b/Sources/Layoutable.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 public protocol Layoutable: AnyObject, Equatable, CustomDebugStringConvertible { associatedtype View: Layoutable diff --git a/Sources/SizeCalculable.swift b/Sources/SizeCalculable.swift index 36d1b89e..9125bbc5 100644 --- a/Sources/SizeCalculable.swift +++ b/Sources/SizeCalculable.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 public protocol SizeCalculable { func sizeThatFits(_ size: CGSize) -> CGSize From f4f55f7012bf868686c1c9d08828b4a5a957a0b9 Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Thu, 14 Jun 2018 08:42:00 -0400 Subject: [PATCH 10/11] Bring back comments from PinLayout commented interface --- Sources/Impl/PinLayoutImpl+Layouting.swift | 10 + Sources/Impl/PinLayoutImpl+Size.swift | 86 +++++++++ Sources/Impl/PinLayoutImpl+WrapContent.swift | 35 ++++ Sources/Impl/PinLayoutImpl.swift | 189 ++++++++++++++++++- 4 files changed, 313 insertions(+), 7 deletions(-) diff --git a/Sources/Impl/PinLayoutImpl+Layouting.swift b/Sources/Impl/PinLayoutImpl+Layouting.swift index 8a8995e3..4e386b34 100644 --- a/Sources/Impl/PinLayoutImpl+Layouting.swift +++ b/Sources/Impl/PinLayoutImpl+Layouting.swift @@ -25,6 +25,16 @@ // MARK: UIView's frame computation methods extension PinLayout { + /** + The method will execute PinLayout commands immediately. This method is **required only if your + source codes should also work in Xcode Playgrounds**. Outside of playgrounds, PinLayout executes + this method implicitly, it is not necessary to call it. + + Examples: + ```swift + view.pin.top(20).width(100).layout() + ``` + */ public func layout() { apply() } diff --git a/Sources/Impl/PinLayoutImpl+Size.swift b/Sources/Impl/PinLayoutImpl+Size.swift index c5bc4486..5da4f740 100644 --- a/Sources/Impl/PinLayoutImpl+Size.swift +++ b/Sources/Impl/PinLayoutImpl+Size.swift @@ -94,16 +94,43 @@ extension PinLayout { return setSize(view.getRect(keepTransform: keepTransform).size, context) } + /** + Set the view aspect ratio. + + AspectRatio is applied only if a single dimension (either width or height) can be determined, + in that case the aspect ratio will be used to compute the other dimension. + + * AspectRatio is defined as the ratio between the width and the height (width / height). + * An aspect ratio of 2 means the width is twice the size of the height. + * AspectRatio respects the min (minWidth/minHeight) and the max (maxWidth/maxHeight) + dimensions of an item. + */ @discardableResult public func aspectRatio(_ ratio: CGFloat) -> PinLayout { return setAdjustSizeType(.aspectRatio(ratio), { "aspectRatio(\(ratio))" }) } + /** + Set the view aspect ratio using another UIView's aspect ratio. + + AspectRatio is applied only if a single dimension (either width or height) can be determined, + in that case the aspect ratio will be used to compute the other dimension. + + * AspectRatio is defined as the ratio between the width and the height (width / height). + * AspectRatio respects the min (minWidth/minHeight) and the max (maxWidth/maxHeight) + dimensions of an item. + */ public func aspectRatio(of view: View) -> PinLayout { let rect = view.getRect(keepTransform: keepTransform) return setAdjustSizeType(.aspectRatio(rect.width / rect.height), { "aspectRatio(of: \(viewDescription(view)))" }) } + /** + 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) public func aspectRatio() -> PinLayout { func context() -> String { return "aspectRatio()" } @@ -121,12 +148,71 @@ extension PinLayout { } #endif + /** + The method adjust the view's size based on the view's `sizeThatFits()` method result. + PinLayout will adjust either the view's width or height based on the `fitType` parameter value. + + Notes: + * If margin rules apply, margins will be applied when determining the reference dimension (width/height). + * The resulting size will always respect `minWidth` / `maxWidth` / `minHeight` / `maxHeight`. + + - Parameter fitType: Identify the reference dimension (width / height) that will be used + to adjust the view's size: + + .width: The method adjust the view's size 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**, if not the **current view's width** + will be used. + * The resulting width will always **match the reference width**. + + .height: The method adjust the view's size 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**, if not the **current view's height** + will be used. + * The resulting height will always **match the reference height**. + + .widthFlexible: Similar to `.width`, except that PinLayout won't constrain the resulting width to + match the reference width. The resulting width may be smaller or 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. + + .heightFlexible: Similar to `.height`, except that PinLayout won't constrain the resulting height to + match the reference height. The resulting height may be smaller or bigger depending on the view's + sizeThatFits(..) method result. + + Examples: + + ``` + // Adjust the view's size based on a width of 100 pixels. + // The resulting width will always match the pinned property `width(100)`. + view.pin.width(100).sizeToFit(.width) + + // Adjust the view's size based on view's current width. + // The resulting width will always match the view's original width. + // The resulting height will never be bigger than the specified `maxHeight`. + view.pin.sizeToFit(.width).maxHeight(100) + + // Adjust the view's size based on 100% of the superview's height. + // The resulting height will always match the pinned property `height(100%)`. + view.pin.height(100%).sizeToFit(.height) + + // Adjust the view's size based on view's current height. + // The resulting width will always match the view's original height. + view.pin.sizeToFit(.height) + + // Since `.widthFlexible` has been specified, its possible that the resulting + // width will be smaller or bigger than 100 pixels, based of the label's sizeThatFits() + // method result. + label.pin.width(100).sizeToFit(.widthFlexible) + ``` + */ @available(OSX 10.10, *) public func sizeToFit(_ fitType: FitType) -> PinLayout { return setAdjustSizeType(fitType.toAdjustSizeType(), { return "sizeToFit(\(fitType.description))" }) } #if os(iOS) || os(tvOS) + @available(*, deprecated, message: "fitSize() is deprecated, please use sizeToFit(fitType: FitType)") public func fitSize() -> PinLayout { return setAdjustSizeType(.fitSizeLegacy, { return "fitSize()" }) } diff --git a/Sources/Impl/PinLayoutImpl+WrapContent.swift b/Sources/Impl/PinLayoutImpl+WrapContent.swift index 3e782d26..75668099 100644 --- a/Sources/Impl/PinLayoutImpl+WrapContent.swift +++ b/Sources/Impl/PinLayoutImpl+WrapContent.swift @@ -24,26 +24,61 @@ import AppKit #endif extension PinLayout { + /** + Adjust the view's width & height to wrap all its subviews. The method also adjust subviews position to create a tight wrap. + */ public func wrapContent() -> PinLayout { return wrapContent(.all, padding: PEdgeInsets(top: 0, left: 0, bottom: 0, right: 0), { return "wrapContent()" }) } + /** + 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. + */ public func wrapContent(padding: CGFloat) -> PinLayout { return wrapContent(.all, padding: PEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), { return "wrapContent(padding: \(padding)" }) } + /** + 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. + */ public func wrapContent(padding: PEdgeInsets) -> PinLayout { return wrapContent(.all, padding: padding, { return "wrapContent(padding: \(insetsDescription(padding))" }) } + /** + Adjust the view's width AND/OR height to wrap all its subviews. + + - Parameters: + - type: Specify the wrap type (.all, .horizontally, .vertically) + */ public func wrapContent(_ type: WrapType) -> PinLayout { return wrapContent(type, padding: PEdgeInsets(top: 0, left: 0, bottom: 0, right: 0), { return "wrapContent(\(type.description)" }) } + /** + 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. + */ public func wrapContent(_ type: WrapType, padding: CGFloat) -> PinLayout { return wrapContent(type, padding: PEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), { return "wrapContent(\(type.description), padding: \(padding)" }) } + /** + 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. + */ public func wrapContent(_ type: WrapType, padding: PEdgeInsets) -> PinLayout { return wrapContent(type, padding: padding, { return "wrapContent(\(type.description), padding: \(insetsDescription(padding))" }) } diff --git a/Sources/Impl/PinLayoutImpl.swift b/Sources/Impl/PinLayoutImpl.swift index b0c13bac..5d3a2b45 100644 --- a/Sources/Impl/PinLayoutImpl.swift +++ b/Sources/Impl/PinLayoutImpl.swift @@ -98,9 +98,12 @@ public class PinLayout { } #endif + // + // MARK: Layout using distances from superview’s edges // // top, left, bottom, right // + public func top() -> PinLayout { top({ return "top()" }) return self @@ -251,6 +254,13 @@ public class PinLayout { return self } + // Pin multiple edges at once. + + /** + Pin all edges on its superview's corresponding edges (top, bottom, left, right). + + Similar to calling `view.top().bottom().left().right()` + */ public func all() -> PinLayout { top({ "all() top coordinate" }) bottom({ "all() bottom coordinate" }) @@ -259,6 +269,11 @@ public class PinLayout { return self } + /** + Pin all edges on its superview's corresponding edges (top, bottom, left, right). + + Similar to calling `view.top().bottom().left().right()` + */ public func all(_ value: CGFloat) -> PinLayout { top(value, { "all(\(value)) top coordinate" }) bottom(value, { "all(\(value)) bottom coordinate" }) @@ -267,6 +282,11 @@ public class PinLayout { return self } + /** + Pin all edges on its superview's corresponding edges (top, bottom, left, right). + + Similar to calling `view.top().bottom().left().right()` + */ public func all(_ insets: PEdgeInsets) -> PinLayout { top(insets.top, { "all(\(insets)) top coordinate" }) bottom(insets.bottom, { "all(\(insets)) bottom coordinate" }) @@ -275,57 +295,100 @@ public class PinLayout { return self } + /** + Pin the left and right edges on its superview's corresponding edges. + + Similar to calling `view.left().right()`. + */ public func horizontally() -> PinLayout { right({ "horizontally() right coordinate" }) left({ "horizontally() left coordinate" }) return self } + /** + Pin the left and right edges on its superview's corresponding edges. + + Similar to calling `view.left().right()`. + */ public func horizontally(_ value: CGFloat) -> PinLayout { left(value, { return "horizontally(\(value)) left coordinate" }) right(value, { return "horizontally(\(value)) right coordinate" }) return self } + /** + Pin the left and right edges on its superview's corresponding edges. + + Similar to calling `view.left().right()`. + */ public func horizontally(_ percent: Percent) -> PinLayout { left(percent, { return "horizontally(\(percent.description)) left coordinate" }) right(percent, { return "horizontally(\(percent.description)) right coordinate" }) return self } + /** + Pin the left and right edges on its superview's corresponding edges. + + Similar to calling `view.left().right()`. + */ public func horizontally(_ insets: PEdgeInsets) -> PinLayout { left(insets.left, { return "horizontally(\(insets)) left coordinate" }) right(insets.right, { return "horizontally(\(insets)) right coordinate" }) return self } + /** + Pin the **top and bottom edges** on its superview's corresponding edges. + + Similar to calling `view.top().bottom()`. + */ public func vertically() -> PinLayout { top({ "vertically() top coordinate" }) bottom({ "vertically() bottom coordinate" }) return self } + /** + Pin the **top and bottom edges** on its superview's corresponding edges. + + Similar to calling `view.top().bottom()`. + */ public func vertically(_ value: CGFloat) -> PinLayout { top(value, { return "vertically(\(value)) top coordinate" }) bottom(value, { return "vertically(\(value)) bottom coordinate" }) return self } + /** + Pin the **top and bottom edges** on its superview's corresponding edges. + + Similar to calling `view.top().bottom()`. + */ public func vertically(_ percent: Percent) -> PinLayout { top(percent, { return "vertically(\(percent.description)) top coordinate" }) bottom(percent, { return "vertically(\(percent.description)) bottom coordinate" }) return self } + /** + Pin the **top and bottom edges** on its superview's corresponding edges. + The UIEdgeInsets.top is used to pin the top edge and the UIEdgeInsets.bottom + for the bottom edge. + */ public func vertically(_ insets: PEdgeInsets) -> PinLayout { top(insets.top, { return "vertically(\(insets)) top coordinate" }) bottom(insets.bottom, { return "vertically(\(insets)) bottom coordinate" }) return self } + // + // MARK: Layout using edges // // top, left, bottom, right // + public func top(to edge: VerticalEdge) -> PinLayout { func context() -> String { return relativeEdgeContext(method: "top", edge: edge) } if let coordinate = computeCoordinate(forEdge: edge, context) { @@ -389,12 +452,15 @@ public class PinLayout { } return self } - + + // + // MARK: Layout using anchors // // topLeft, topCenter, topRight, // centerLeft, center, centerRight, // bottomLeft, bottomCenter, bottomRight, // + public func topLeft(to anchor: Anchor) -> PinLayout { func context() -> String { return relativeAnchorContext(method: "topLeft", anchor: anchor) } if let coordinatesList = computeCoordinates(forAnchors: [anchor], context) { @@ -632,8 +698,9 @@ public class PinLayout { } // - // width, height + // MARK: Width, height // + public func width(_ width: CGFloat) -> PinLayout { return setWidth(width, { return "width(\(width))" }) } @@ -707,10 +774,11 @@ public class PinLayout { guard let layoutSuperviewRect = layoutSuperviewRect(context) else { return self } return setMaxHeight(percent.of(layoutSuperviewRect.height), context) } - + // - // justify, align + // MARK: justify / align // + public func justify(_ value: HorizontalAlign) -> PinLayout { justify = value return self @@ -722,13 +790,20 @@ public class PinLayout { } // - // Margins + // MARK: Margins // + + /** + Set the top margin. + */ public func marginTop(_ value: CGFloat) -> PinLayout { marginTop = value return self } + /** + Set the top margin. + */ public func marginTop(_ percent: Percent) -> PinLayout { func context() -> String { return "marginTop(\(percent.description))" } return marginTop(percent, context) @@ -740,11 +815,17 @@ public class PinLayout { return self } + /** + Set the left margin. + */ public func marginLeft(_ value: CGFloat) -> PinLayout { marginLeft = value return self } + /** + Set the left margin. + */ public func marginLeft(_ percent: Percent) -> PinLayout { func context() -> String { return "marginLeft(\(percent.description))" } return marginLeft(percent, context) @@ -756,11 +837,17 @@ public class PinLayout { return self } + /** + Set the bottom margin. + */ public func marginBottom(_ value: CGFloat) -> PinLayout { marginBottom = value return self } + /** + Set the bottom margin. + */ public func marginBottom(_ percent: Percent) -> PinLayout { func context() -> String { return "marginBottom(\(percent.description))" } return marginBottom(percent, context) @@ -772,11 +859,17 @@ public class PinLayout { return self } + /** + Set the right margin. + */ public func marginRight(_ value: CGFloat) -> PinLayout { marginRight = value return self } + /** + Set the right margin. + */ public func marginRight(_ percent: Percent) -> PinLayout { func context() -> String { return "marginRight(\(percent.description))" } return marginRight(percent, context) @@ -788,32 +881,68 @@ public class PinLayout { return self } + // RTL support + + /** + Set the start margin. + + Depends on the value of `Pin.layoutDirection(...)`: + * In LTR direction, start margin specify the **left** margin. + * In RTL direction, start margin specify the **right** margin. + */ @discardableResult public func marginStart(_ value: CGFloat) -> PinLayout { return isLTR() ? marginLeft(value) : marginRight(value) } + /** + Set the start margin. + + Depends on the value of `Pin.layoutDirection(...)`: + * In LTR direction, start margin specify the **left** margin. + * In RTL direction, start margin specify the **right** margin. + */ public func marginStart(_ percent: Percent) -> PinLayout { func context() -> String { return "marginStart(\(percent.description))" } return isLTR() ? marginLeft(percent, context) : marginRight(percent, context) } - + + /** + Set the end margin. + + Depends on the value of `Pin.layoutDirection(...)`: + * In LTR direction, end margin specify the **right** margin. + * In RTL direction, end margin specify the **left** margin. + */ @discardableResult public func marginEnd(_ value: CGFloat) -> PinLayout { return isLTR() ? marginRight(value) : marginLeft(value) } + /** + Set the end margin. + + Depends on the value of `Pin.layoutDirection(...)`: + * In LTR direction, end margin specify the **right** margin. + * In RTL direction, end margin specify the **left** margin. + */ public func marginEnd(_ percent: Percent) -> PinLayout { func context() -> String { return "marginEnd(\(percent.description))" } return isLTR() ? marginRight(percent, context) : marginLeft(percent, context) } + /** + Set the left, right, start and end margins to the specified value. + */ public func marginHorizontal(_ value: CGFloat) -> PinLayout { marginLeft = value marginRight = value return self } + /** + Set the left, right, start and end margins to the specified value. + */ public func marginHorizontal(_ percent: Percent) -> PinLayout { func context() -> String { return "marginHorizontal(\(percent.description))" } return marginHorizontal(percent, context) @@ -823,12 +952,18 @@ public class PinLayout { return marginLeft(percent, context).marginRight(percent, context) } + /** + Set the top and bottom margins to the specified value. + */ public func marginVertical(_ value: CGFloat) -> PinLayout { marginTop = value marginBottom = value return self } + /** + Set the top and bottom margins to the specified value. + */ public func marginVertical(_ percent: Percent) -> PinLayout { func context() -> String { return "marginVertical(\(percent.description))" } return marginVertical(percent, context) @@ -837,7 +972,11 @@ public class PinLayout { private func marginVertical(_ percent: Percent, _ context: Context) -> Self { return marginTop(percent, context).marginBottom(percent, context) } - + + /** + Set all margins using UIEdgeInsets. + This method is particularly useful to set all margins using iOS 11 `UIView.safeAreaInsets`. + */ public func margin(_ insets: PEdgeInsets) -> PinLayout { marginTop = insets.top marginBottom = insets.bottom @@ -846,6 +985,12 @@ public class PinLayout { return self } + /** + Set margins using NSDirectionalEdgeInsets. + This method is particularly to set all margins using iOS 11 `UIView.directionalLayoutMargins`. + + Available only on iOS 11 and higher. + */ #if os(iOS) || os(tvOS) @available(tvOS 11.0, iOS 11.0, *) public func margin(_ directionalInsets: NSDirectionalEdgeInsets) -> PinLayout { @@ -857,6 +1002,9 @@ public class PinLayout { } #endif + /** + Set all margins to the specified value. + */ public func margin(_ value: CGFloat) -> PinLayout { marginTop = value marginLeft = value @@ -865,6 +1013,9 @@ public class PinLayout { return self } + /** + Set all margins to the specified value. + */ public func margin(_ percent: Percent) -> PinLayout { func context() -> String { return "margin(\(percent.description))" } return marginTop(percent, context) @@ -873,6 +1024,9 @@ public class PinLayout { .marginRight(percent, context) } + /** + Set individually top, horizontal margins and bottom margin. + */ public func margin(_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) -> PinLayout { marginTop = top marginLeft = left @@ -881,6 +1035,9 @@ public class PinLayout { return self } + /** + Set individually top, horizontal margins and bottom margin. + */ public 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)" @@ -891,6 +1048,9 @@ public class PinLayout { .marginRight(right, context) } + /** + Set individually vertical margins (top, bottom) and horizontal margins (left, right, start, end). + */ public func margin(_ vertical: CGFloat, _ horizontal: CGFloat) -> PinLayout { marginTop = vertical marginLeft = horizontal @@ -899,11 +1059,17 @@ public class PinLayout { return self } + /** + Set individually vertical margins (top, bottom) and horizontal margins (left, right, start, end). + */ public 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) } + /** + Set individually top, horizontal margins and bottom margin. + */ public func margin(_ top: CGFloat, _ horizontal: CGFloat, _ bottom: CGFloat) -> PinLayout { marginTop = top marginLeft = horizontal @@ -912,11 +1078,20 @@ public class PinLayout { return self } + /** + Set individually top, horizontal margins and bottom margin. + */ public 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) } + /// Normally if only either left or right has been specified, PinLayout will MOVE the view to apply left or right margins. + /// This is also true even if the width has been set. + /// Calling pinEdges() will force PinLayout to pin the four edges and then apply left and/or right margins, and this without + /// moving the view. + /// + /// - Returns: PinLayout public func pinEdges() -> PinLayout { shouldPinEdges = true return self From 331757aab589ee76f9606af46eed59f60b15f407 Mon Sep 17 00:00:00 2001 From: Antoine Lamy Date: Thu, 14 Jun 2018 16:21:10 -0400 Subject: [PATCH 11/11] Drop support for macOS 10.9 and bump deployment target to 10.10 --- PinLayout.podspec | 2 +- PinLayout.xcodeproj/project.pbxproj | 4 ++-- Podfile | 2 +- Sources/Impl/PinLayoutImpl+Layouting.swift | 4 +--- Sources/Impl/PinLayoutImpl+Size.swift | 1 - Sources/NSView+PinLayout.swift | 1 - Sources/ObjectiveC/PinLayoutObjC.swift | 1 - Sources/ObjectiveC/PinLayoutObjCImpl.swift | 1 - 8 files changed, 5 insertions(+), 11 deletions(-) diff --git a/PinLayout.podspec b/PinLayout.podspec index 113ce5ff..709400e6 100644 --- a/PinLayout.podspec +++ b/PinLayout.podspec @@ -24,6 +24,6 @@ Pod::Spec.new do |spec| spec.tvos.deployment_target = '9.0' spec.tvos.frameworks = 'Foundation', 'CoreGraphics', 'UIKit' - spec.osx.deployment_target = '10.9' + spec.osx.deployment_target = '10.10' spec.osx.frameworks = 'Foundation', 'CoreGraphics', 'AppKit' end diff --git a/PinLayout.xcodeproj/project.pbxproj b/PinLayout.xcodeproj/project.pbxproj index b249a2db..c653fc50 100644 --- a/PinLayout.xcodeproj/project.pbxproj +++ b/PinLayout.xcodeproj/project.pbxproj @@ -1328,7 +1328,7 @@ INFOPLIST_FILE = Sources/SupportingFiles/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.9; + MACOSX_DEPLOYMENT_TARGET = 10.10; PRODUCT_BUNDLE_IDENTIFIER = "com.layoutbox.PinLayout-macOS"; PRODUCT_NAME = PinLayout; SDKROOT = macosx; @@ -1360,7 +1360,7 @@ INFOPLIST_FILE = Sources/SupportingFiles/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.9; + MACOSX_DEPLOYMENT_TARGET = 10.10; PRODUCT_BUNDLE_IDENTIFIER = "com.layoutbox.PinLayout-macOS"; PRODUCT_NAME = PinLayout; SDKROOT = macosx; diff --git a/Podfile b/Podfile index 8b197a0c..9b22165d 100644 --- a/Podfile +++ b/Podfile @@ -38,7 +38,7 @@ target 'PinLayoutSample' do end #target 'PinLayoutMacOsSample' do -# platform :osx, '10.9' +# platform :osx, '10.10' # project 'Example/PinLayoutMacOsSample.xcodeproj' # # pod 'PinLayout', :path => './' diff --git a/Sources/Impl/PinLayoutImpl+Layouting.swift b/Sources/Impl/PinLayoutImpl+Layouting.swift index 4e386b34..144ef49a 100644 --- a/Sources/Impl/PinLayoutImpl+Layouting.swift +++ b/Sources/Impl/PinLayoutImpl+Layouting.swift @@ -197,7 +197,7 @@ extension PinLayout { private func computeSize() -> Size { var size = resolveSize() - if #available(OSX 10.10, *), let adjustSizeType = adjustSizeType { + if let adjustSizeType = adjustSizeType { switch adjustSizeType { case .fitTypeWidth, .fitTypeHeight, .fitTypeWidthFlexible, .fitTypeHeightFlexible: size = computeSizeToFit(adjustSizeType: adjustSizeType, size: size) @@ -236,7 +236,6 @@ extension PinLayout { return size } - @available(OSX 10.10, *) private func computeLegacyFitSize(size: Size) -> Size { guard let sizeCalculableView = view as? SizeCalculable else { assertionFailure("Should not occurs, protocol conformance is checked before assigning adjustSizeType") @@ -275,7 +274,6 @@ extension PinLayout { return size } - @available(OSX 10.10, *) private func computeSizeToFit(adjustSizeType: AdjustSizeType, size: Size) -> Size { guard let sizeCalculableView = view as? SizeCalculable else { assertionFailure("Should not occurs, protocol conformance is checked before assigning adjustSizeType") diff --git a/Sources/Impl/PinLayoutImpl+Size.swift b/Sources/Impl/PinLayoutImpl+Size.swift index 5da4f740..665e8f60 100644 --- a/Sources/Impl/PinLayoutImpl+Size.swift +++ b/Sources/Impl/PinLayoutImpl+Size.swift @@ -206,7 +206,6 @@ extension PinLayout { label.pin.width(100).sizeToFit(.widthFlexible) ``` */ - @available(OSX 10.10, *) public func sizeToFit(_ fitType: FitType) -> PinLayout { return setAdjustSizeType(fitType.toAdjustSizeType(), { return "sizeToFit(\(fitType.description))" }) } diff --git a/Sources/NSView+PinLayout.swift b/Sources/NSView+PinLayout.swift index e31ba8cc..5d85ea25 100644 --- a/Sources/NSView+PinLayout.swift +++ b/Sources/NSView+PinLayout.swift @@ -61,7 +61,6 @@ extension NSView: Layoutable { } } -@available(OSX 10.10, *) extension NSControl: SizeCalculable { } diff --git a/Sources/ObjectiveC/PinLayoutObjC.swift b/Sources/ObjectiveC/PinLayoutObjC.swift index 82b0be83..0eb16a64 100644 --- a/Sources/ObjectiveC/PinLayoutObjC.swift +++ b/Sources/ObjectiveC/PinLayoutObjC.swift @@ -278,7 +278,6 @@ import AppKit @discardableResult func aspectRatio() -> PinLayoutObjC #endif - @available(OSX 10.10, *) @discardableResult func sizeToFit(_ fitType: Fit) -> PinLayoutObjC // diff --git a/Sources/ObjectiveC/PinLayoutObjCImpl.swift b/Sources/ObjectiveC/PinLayoutObjCImpl.swift index b6ffd878..6f8f2535 100644 --- a/Sources/ObjectiveC/PinLayoutObjCImpl.swift +++ b/Sources/ObjectiveC/PinLayoutObjCImpl.swift @@ -643,7 +643,6 @@ import AppKit } #endif - @available(OSX 10.10, *) func sizeToFit(_ fitType: Fit) -> PinLayoutObjC { let type: FitType switch fitType {