From 0282117fcea40f75966e45170bf86930ef5c6537 Mon Sep 17 00:00:00 2001 From: Nick Entin Date: Sun, 28 Jul 2024 02:10:21 -0700 Subject: [PATCH 1/2] Add support for slicing from directional edges Currently slicing uses min/max x/y definitions for specifying edges. Adding an API for specifying leading/trailing edges (as well as top/bottom for convenience) makes layout easier for apps that support both LTR and RTL layout. --- Paralayout/GeometryAdditions.swift | 36 ++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/Paralayout/GeometryAdditions.swift b/Paralayout/GeometryAdditions.swift index 9d0e3ac..28084fa 100644 --- a/Paralayout/GeometryAdditions.swift +++ b/Paralayout/GeometryAdditions.swift @@ -91,6 +91,13 @@ extension CGSize { // MARK: - +public enum DirectionalEdge { + case top + case bottom + case leading + case trailing +} + extension CGRect { /// Initialize a CGRect with bounding coordinates (always with non-negative size). @@ -141,10 +148,35 @@ extension CGRect { public func offset(by offset: UIOffset) -> CGRect { return CGRect(origin: origin.offset(by: offset), size: size) } - + + /// Divides the receiver in two. + /// + /// - parameter edge: The edge from which the amount is interpreted. + /// - parameter amount: The size of the slice (absolute). + /// - returns: A tuple (slice: A rect with a width/height of the `amount`, remainder: A rect with a width/height of + /// the receiver reduced by `amount`). + public func slice( + from edge: DirectionalEdge, + amount: CGFloat, + in layoutDirectionProvider: LayoutDirectionProviding + ) -> (slice: CGRect, remainder: CGRect) { + switch (edge, layoutDirectionProvider.effectiveUserInterfaceLayoutDirection) { + case (.top, _): + slice(from: .minYEdge, amount: amount) + case (.bottom, _): + slice(from: .maxYEdge, amount: amount) + case (.leading, .leftToRight), (.trailing, .rightToLeft): + slice(from: .minXEdge, amount: amount) + case (.trailing, .leftToRight), (.leading, .rightToLeft): + slice(from: .maxXEdge, amount: amount) + @unknown default: + fatalError("Unknown user interface layout direction") + } + } + /// Divides the receiver in two. /// - /// - parameter from: The edge from which the amount is interpreted. + /// - parameter edge: The edge from which the amount is interpreted. /// - parameter amount: The size of the slice (absolute). /// - returns: A tuple (slice: A rect with a width/height of the `amount`, remainder: A rect with a width/height of /// the receiver reduced by `amount`). From e1351b10a4dcc93d59b4a3b58c34b4ec6a5baea9 Mon Sep 17 00:00:00 2001 From: Nick Entin Date: Fri, 30 Aug 2024 15:46:03 -0700 Subject: [PATCH 2/2] Make method main actor --- Paralayout/GeometryAdditions.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Paralayout/GeometryAdditions.swift b/Paralayout/GeometryAdditions.swift index 28084fa..cd9d4d0 100644 --- a/Paralayout/GeometryAdditions.swift +++ b/Paralayout/GeometryAdditions.swift @@ -155,6 +155,7 @@ extension CGRect { /// - parameter amount: The size of the slice (absolute). /// - returns: A tuple (slice: A rect with a width/height of the `amount`, remainder: A rect with a width/height of /// the receiver reduced by `amount`). + @MainActor public func slice( from edge: DirectionalEdge, amount: CGFloat,