From 4d5feb387099c4c0f719fcc5b49546d862cc4954 Mon Sep 17 00:00:00 2001 From: Muukii Date: Tue, 15 Oct 2024 23:53:43 +0900 Subject: [PATCH 1/3] Patch --- .../SwiftUISupportLayout/RelativeView.swift | 134 ++++++------------ 1 file changed, 42 insertions(+), 92 deletions(-) diff --git a/Sources/SwiftUISupportLayout/RelativeView.swift b/Sources/SwiftUISupportLayout/RelativeView.swift index 97d2db8c66..dc9ddb2219 100644 --- a/Sources/SwiftUISupportLayout/RelativeView.swift +++ b/Sources/SwiftUISupportLayout/RelativeView.swift @@ -1,67 +1,5 @@ import SwiftUI -public enum RelativeHorizontalPosition { - case left - case center - case right -} - -public enum RelativeVerticalPosition { - case top - case center - case bottom -} - -/// A container view that places the content in the specified position. -/// A useful case will be placing the content on the corner of the parent view. -@available(*, deprecated, message: "Use modifier instead") -public struct RelativeView: View { - - public let content: Content - public let vertical: RelativeVerticalPosition - public let horizontal: RelativeHorizontalPosition - - public init( - vertical: RelativeVerticalPosition, - horizontal: RelativeHorizontalPosition, - @ViewBuilder content: () -> Content - ) { - self.vertical = vertical - self.horizontal = horizontal - self.content = content() - } - - public var body: some View { - - let horizontalContent: some View = HStack { - switch horizontal { - case .left: - content - Spacer(minLength: 0) - case .center: - content - case .right: - Spacer(minLength: 0) - content - } - } - - VStack { - switch vertical { - case .top: - horizontalContent - Spacer(minLength: 0) - case .center: - horizontalContent - case .bottom: - Spacer(minLength: 0) - horizontalContent - } - } - - } -} - /// like align-self public struct RelativeLayoutModifier: ViewModifier { @@ -133,37 +71,49 @@ extension View { } -enum Preview_AnchorView: PreviewProvider { - - static var previews: some View { - Rectangle() - .frame(width: 50, height: 50) - .overlay( - RelativeView(vertical: .top, horizontal: .right) { - Circle() - .foregroundColor(.red) - .frame(width: 20, height: 20) - } +#Preview { + Rectangle() + .frame(width: 50, height: 50) + .overlay( + Circle() + .foregroundColor(.red) + .frame(width: 20, height: 20) + .relative(vertical: .top, horizontal: .trailing) .offset(x: 10, y: -10) - ) - - Rectangle() - .frame(width: 50, height: 50) - .overlay( - Circle() - .foregroundColor(.red) - .frame(width: 20, height: 20) - .relative(vertical: .top, horizontal: .trailing) - .offset(x: 10, y: -10) - ) - - HStack { - Text("A") - Text("B") - Text("C") - } - .environment(\.layoutDirection, .rightToLeft) - + ) + + Rectangle() + .frame(width: 50, height: 50) + .overlay( + Circle() + .foregroundColor(.red) + .frame(width: 20, height: 20) + .relative(vertical: .top, horizontal: .trailing) + .offset(x: 10, y: -10) + ) + + HStack { + Text("A") + Text("B") + Text("C") } + .environment(\.layoutDirection, .rightToLeft) +} +#Preview("Using Aligment guide") { + + Rectangle() + .frame(width: 50, height: 50) + .overlay(alignment: .topTrailing) { + Circle() + .fill(.blue) + .frame(width: 20, height: 20) + .alignmentGuide(.top) { d in + return d[.top] + d.height / 2 + } + .alignmentGuide(.trailing) { d in + return d[.trailing] - d.width / 2 + } + } + .background(Color.purple) } From 52a32d5f643245391398671a4eda90dcd626d479 Mon Sep 17 00:00:00 2001 From: Muukii Date: Wed, 16 Oct 2024 19:09:37 +0900 Subject: [PATCH 2/3] Update --- Sources/SwiftUISupportLayout/Anchoring.swift | 28 +++ .../SwiftUISupportLayout/RelativeView.swift | 196 ++++++++++-------- 2 files changed, 138 insertions(+), 86 deletions(-) create mode 100644 Sources/SwiftUISupportLayout/Anchoring.swift diff --git a/Sources/SwiftUISupportLayout/Anchoring.swift b/Sources/SwiftUISupportLayout/Anchoring.swift new file mode 100644 index 0000000000..9113122a84 --- /dev/null +++ b/Sources/SwiftUISupportLayout/Anchoring.swift @@ -0,0 +1,28 @@ +import SwiftUI + +#Preview("Using Aligment guide") { + + Rectangle() + .frame(width: 50, height: 50) + .anchoring { + Circle() + .fill(.blue) + } + .background(Color.purple) +} + +extension View { + + public func anchoring(@ViewBuilder content: () -> some View) -> some View { + overlay(alignment: .topTrailing) { + content() + .alignmentGuide(.top) { d in + d[.top] + d.height / 2 + } + .alignmentGuide(.trailing) { d in + d[.trailing] - d.width / 2 + } + } + } + +} diff --git a/Sources/SwiftUISupportLayout/RelativeView.swift b/Sources/SwiftUISupportLayout/RelativeView.swift index dc9ddb2219..a72583c804 100644 --- a/Sources/SwiftUISupportLayout/RelativeView.swift +++ b/Sources/SwiftUISupportLayout/RelativeView.swift @@ -1,59 +1,22 @@ import SwiftUI -/// like align-self -public struct RelativeLayoutModifier: ViewModifier { +/// deprecated +public struct RelativeLayoutModifier { public enum HorizontalPosition { case leading + @available(*, unavailable) case center case trailing } public enum VerticalPosition { case top + @available(*, unavailable) case center case bottom } - public let vertical: VerticalPosition - public let horizontal: HorizontalPosition - - public init( - vertical: VerticalPosition, - horizontal: HorizontalPosition - ) { - self.vertical = vertical - self.horizontal = horizontal - } - - public func body(content: Content) -> some View { - let horizontalContent: some View = HStack { - switch horizontal { - case .leading: - content - Spacer(minLength: 0) - case .center: - content - case .trailing: - Spacer(minLength: 0) - content - } - } - - VStack { - switch vertical { - case .top: - horizontalContent - Spacer(minLength: 0) - case .center: - horizontalContent - case .bottom: - Spacer(minLength: 0) - horizontalContent - } - } - } - } extension View { @@ -62,58 +25,119 @@ extension View { * Lays out the view and positions it within the layout bounds according to vertical and horizontal positional specifiers. * Can position the child at any of the 4 corners, or the middle of any of the 4 edges, as well as the center - similar to "9-part" image areas. */ + @available(*, deprecated, message: "use relative(alignment: )") public func relative( - vertical: RelativeLayoutModifier.VerticalPosition = .center, - horizontal: RelativeLayoutModifier.HorizontalPosition = .center + vertical: RelativeLayoutModifier.VerticalPosition, + horizontal: RelativeLayoutModifier.HorizontalPosition ) -> some View { - self.modifier(RelativeLayoutModifier(vertical: vertical, horizontal: horizontal)) - } - -} - -#Preview { - Rectangle() - .frame(width: 50, height: 50) - .overlay( - Circle() - .foregroundColor(.red) - .frame(width: 20, height: 20) - .relative(vertical: .top, horizontal: .trailing) - .offset(x: 10, y: -10) + + return self.relative(alignment: .init( + horizontal: { + switch horizontal { + case .center: + return .center + case .leading: + return .leading + case .trailing: + return .trailing + } + }(), + vertical: { + switch vertical { + case .center: + return .center + case .top: + return .top + case .bottom: + return .bottom + } + }() ) + ) + } + + @available(*, deprecated, message: "use relative(alignment: )") + public func relative( + horizontal: RelativeLayoutModifier.HorizontalPosition + ) -> some View { + + return self.relative(horizontalAlignment: { + switch horizontal { + case .center: + return .center + case .leading: + return .leading + case .trailing: + return .trailing + } + }() + ) + } + + @available(*, deprecated, message: "use relative(alignment: )") + public func relative( + vertical: RelativeLayoutModifier.VerticalPosition + ) -> some View { + + return self.relative(verticalAlignment: { + switch vertical { + case .center: + return .center + case .top: + return .top + case .bottom: + return .bottom + } + }() + ) + } - Rectangle() - .frame(width: 50, height: 50) - .overlay( - Circle() - .foregroundColor(.red) - .frame(width: 20, height: 20) - .relative(vertical: .top, horizontal: .trailing) - .offset(x: 10, y: -10) + public func relative( + alignment: Alignment + ) -> some View { + self.frame( + maxWidth: .infinity, + maxHeight: .infinity, + alignment: alignment ) + } - HStack { - Text("A") - Text("B") - Text("C") + public func relative( + horizontalAlignment: HorizontalAlignment + ) -> some View { + self.frame(maxWidth: .infinity, alignment: .init(horizontal: horizontalAlignment, vertical: .center)) + } + + public func relative( + verticalAlignment: VerticalAlignment + ) -> some View { + self.frame(maxHeight: .infinity, alignment: .init(horizontal: .center, vertical: verticalAlignment)) + } + + public func relative( + horizontalAlignment: HorizontalAlignment, + verticalAlignment: VerticalAlignment + ) -> some View { + self.frame( + maxWidth: .infinity, + maxHeight: .infinity, + alignment: .init(horizontal: horizontalAlignment, vertical: verticalAlignment) + ) } - .environment(\.layoutDirection, .rightToLeft) + } -#Preview("Using Aligment guide") { - - Rectangle() - .frame(width: 50, height: 50) - .overlay(alignment: .topTrailing) { - Circle() - .fill(.blue) - .frame(width: 20, height: 20) - .alignmentGuide(.top) { d in - return d[.top] + d.height / 2 - } - .alignmentGuide(.trailing) { d in - return d[.trailing] - d.width / 2 - } - } - .background(Color.purple) +#Preview { + HStack(alignment: .top) { + + Rectangle() + .frame(width: 100, height: 100) + + Rectangle() + .frame(width: 50, height: 50) + .foregroundColor(.red) + .relative(verticalAlignment: .center) + + } + .background(Color.green) } From 5f912645960d9c54caea212081563b838e931590 Mon Sep 17 00:00:00 2001 From: Muukii Date: Wed, 16 Oct 2024 19:10:31 +0900 Subject: [PATCH 3/3] Update --- Sources/SwiftUISupportLayout/Anchoring.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftUISupportLayout/Anchoring.swift b/Sources/SwiftUISupportLayout/Anchoring.swift index 9113122a84..7b8874a1f4 100644 --- a/Sources/SwiftUISupportLayout/Anchoring.swift +++ b/Sources/SwiftUISupportLayout/Anchoring.swift @@ -1,5 +1,8 @@ import SwiftUI +#if DEBUG +// still in development + #Preview("Using Aligment guide") { Rectangle() @@ -13,7 +16,7 @@ import SwiftUI extension View { - public func anchoring(@ViewBuilder content: () -> some View) -> some View { + internal func anchoring(@ViewBuilder content: () -> some View) -> some View { overlay(alignment: .topTrailing) { content() .alignmentGuide(.top) { d in @@ -26,3 +29,5 @@ extension View { } } + +#endif