diff --git a/Example/OpenSwiftUIUITests/Layout/Geometry/GeometryReaderUITests.swift b/Example/OpenSwiftUIUITests/Layout/Geometry/GeometryReaderUITests.swift index a2783e0b2..8be69e0b3 100644 --- a/Example/OpenSwiftUIUITests/Layout/Geometry/GeometryReaderUITests.swift +++ b/Example/OpenSwiftUIUITests/Layout/Geometry/GeometryReaderUITests.swift @@ -4,35 +4,14 @@ import SnapshotTesting import Testing +@testable import TestingHost @MainActor @Suite(.snapshots(record: .never, diffTool: diffTool)) struct GeometryReaderUITests { @Test(.bug("https://github.com/OpenSwiftUIProject/OpenSwiftUI/issues/474")) func centerView() { - struct ContentView: View { - var body: some View { - GeometryReader { proxy in - Color.blue - .frame( - width: proxy.size.width / 2, - height: proxy.size.height / 2, - ) - .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color.yellow.opacity(0.3)) - } - } - } - openSwiftUIAssertSnapshot(of: ContentView()) - #if os(iOS) - #if OPENSWIFTUI - withKnownIssue { - openSwiftUIAssertSnapshot(of: ContentView(), as: .image) - } - #else - openSwiftUIAssertSnapshot(of: ContentView(), as: .image) - #endif - #endif + openSwiftUIAssertSnapshot(of: GeometryReaderExample()) } @Test diff --git a/Example/Shared/Layout/Geometry/GeometryReaderExample.swift b/Example/Shared/Layout/Geometry/GeometryReaderExample.swift index bba3d90af..663bc4c8f 100644 --- a/Example/Shared/Layout/Geometry/GeometryReaderExample.swift +++ b/Example/Shared/Layout/Geometry/GeometryReaderExample.swift @@ -8,8 +8,6 @@ import OpenSwiftUI import SwiftUI #endif -// FIXME: SwiftUI yellow background will ignoreSafeArea while OpenSwiftUI will have it. -// See #474 struct GeometryReaderExample: View { var body: some View { GeometryReader { geometry in diff --git a/Sources/OpenSwiftUICore/Layout/Geometry/Anchor.swift b/Sources/OpenSwiftUICore/Layout/Geometry/Anchor.swift index 4281c3549..a457abab7 100644 --- a/Sources/OpenSwiftUICore/Layout/Geometry/Anchor.swift +++ b/Sources/OpenSwiftUICore/Layout/Geometry/Anchor.swift @@ -189,7 +189,9 @@ private class AnchorValueBox: AnchorValueBoxBase, @unchecked S } override func convert(to transform: ViewTransform) -> T.AnchorValue { - _openSwiftUIUnimplementedFailure() + var value = value + value.convert(to: .global, transform: transform) + return value } override func isEqual(to other: AnchorValueBoxBase) -> Bool { diff --git a/Sources/OpenSwiftUICore/Layout/Geometry/GeometryReader.swift b/Sources/OpenSwiftUICore/Layout/Geometry/GeometryReader.swift index c77c9457e..b74d29297 100644 --- a/Sources/OpenSwiftUICore/Layout/Geometry/GeometryReader.swift +++ b/Sources/OpenSwiftUICore/Layout/Geometry/GeometryReader.swift @@ -3,14 +3,14 @@ // OpenSwiftUICore // // Audited for 6.5.4 -// Status: WIP +// Status: Complete // ID: 7D6D22DF7076CCC1FC5284D8E2D1B049 (SwiftUICore) public import Foundation package import OpenAttributeGraphShims import OpenSwiftUI_SPI -// MARK: - GeometryReader [WIP] +// MARK: - GeometryReader /// A container view that defines its content as a function of its own size and /// coordinate space. @@ -80,7 +80,7 @@ public struct GeometryReader: View, UnaryView, PrimitiveView where Cont mutating func updateValue() { seed &+= 1 let proxy = GeometryProxy( - owner: .current!, + owner: attribute.identifier, size: $size, environment: $environment, transform: $transform, @@ -101,7 +101,7 @@ public struct GeometryReader: View, UnaryView, PrimitiveView where Cont @available(*, unavailable) extension GeometryReader: Sendable {} -// MARK: - GeometryProxy [WIP] +// MARK: - GeometryProxy /// A proxy for access to the size and coordinate space (for anchor resolution) /// of the container view. @@ -169,7 +169,9 @@ public struct GeometryProxy { /// Resolves the value of an anchor to the container view. public subscript(anchor: Anchor) -> T { - _openSwiftUIUnimplementedFailure() + Update.perform { + placementContext.map { anchor.in($0) } ?? anchor.defaultValue + } } /// The safe area inset of the container view. @@ -188,28 +190,41 @@ public struct GeometryProxy { @available(*, deprecated, message: "use overload that accepts a CoordinateSpaceProtocol instead") @_disfavoredOverload public func frame(in coordinateSpace: CoordinateSpace) -> CGRect { - let size = size - return Update.perform { - guard let placementContext else { - return .zero - } - var rect = CGRect(origin: .zero, size: size) - rect.convert(from: placementContext, to: coordinateSpace) - return rect - } + rect(CGRect(origin: .zero, size: size), in: coordinateSpace) } @_spi(Private) public func frameClippedToScrollViews(in space: CoordinateSpace) -> (frame: CGRect, exact: Bool) { - _openSwiftUIUnimplementedFailure() + Update.perform { + var rect = CGRect(origin: .zero, size: size) + guard let placementContext else { + return (rect, true) + } + let exact = rect.whileClippingToScrollViewsConvert( + to: space, + transform: placementContext.transform + ) + return (rect, exact) + } } package func rect(_ r: CGRect, in coordinateSpace: CoordinateSpace) -> CGRect { - _openSwiftUIUnimplementedFailure() + Update.perform { + var rect = r + placementContext.map { rect.convert(from: $0, to: coordinateSpace) } + return rect + } } package var transform: ViewTransform { - _openSwiftUIUnimplementedFailure() + Update.perform { + guard let transform = _transform.attribute, + let position = _position.attribute + else { + return ViewTransform() + } + return context[transform].withPosition(context[position]) + } } package var environment: EnvironmentValues { @@ -244,13 +259,13 @@ extension GeometryProxy { /// Returns the given coordinate space's bounds rectangle, converted to the /// local coordinate space. public func bounds(of coordinateSpace: NamedCoordinateSpace) -> CGRect? { - _openSwiftUIUnimplementedFailure() + transform.containingSizedCoordinateSpace(name: coordinateSpace.name) } /// Returns the container view's bounds rectangle, converted to a defined /// coordinate space. public func frame(in coordinateSpace: some CoordinateSpaceProtocol) -> CGRect { - _openSwiftUIUnimplementedFailure() + rect(CGRect(origin: .zero, size: size), in: coordinateSpace.coordinateSpace) } } @@ -260,7 +275,8 @@ extension GeometryProxy { globalPoint: CGPoint, to coordinateSpace: some CoordinateSpaceProtocol, ) -> CGPoint { - _openSwiftUIUnimplementedFailure() + // TBA: ViewTransform + transform.convert(.localToSpace(coordinateSpace.coordinateSpace), point: globalPoint) } } diff --git a/Sources/OpenSwiftUICore/Layout/View/ViewTransform.swift b/Sources/OpenSwiftUICore/Layout/View/ViewTransform.swift index baf5d324b..c8a2c9d0b 100644 --- a/Sources/OpenSwiftUICore/Layout/View/ViewTransform.swift +++ b/Sources/OpenSwiftUICore/Layout/View/ViewTransform.swift @@ -327,7 +327,11 @@ public struct ViewTransform: Equatable, CustomStringConvertible { } package func containingSizedCoordinateSpace(name: CoordinateSpace.Name) -> CGRect? { - _openSwiftUIUnimplementedFailure() + var rect: CGRect? + forEach { item, _ in + item.apply(to: &rect, name: name) + } + return rect } public var description: String { diff --git a/Sources/OpenSwiftUICore/Modifier/ViewModifier/BackgroundModifier.swift b/Sources/OpenSwiftUICore/Modifier/ViewModifier/BackgroundModifier.swift index 5f4b71d3d..986daf5d8 100644 --- a/Sources/OpenSwiftUICore/Modifier/ViewModifier/BackgroundModifier.swift +++ b/Sources/OpenSwiftUICore/Modifier/ViewModifier/BackgroundModifier.swift @@ -1,9 +1,15 @@ // // BackgroundModifier.swift // OpenSwiftUICore -// Status: WIP +// +// Audited for 6.5.4 +// Status: Complete +// ID: 4F6988968057BB8D11F78AD2EE32ACB1 (SwiftUICore) + +package import Foundation +import OpenAttributeGraphShims -// MARK: - BackgroundModifier [6.4.41] +// MARK: - BackgroundModifier /// A modifier that layers a secondary view behind the primary content it /// modifies, while maintaining the layout characteristics of the primary view. @@ -38,11 +44,316 @@ public struct _BackgroundModifier: ViewModifier, MultiViewModifier, } @available(*, unavailable) -extension _BackgroundModifier : Sendable {} +extension _BackgroundModifier: Sendable {} -// TODO +@available(OpenSwiftUI_v1_0, *) +extension _BackgroundModifier: Equatable where Background: Equatable { + nonisolated public static func == (a: _BackgroundModifier, b: _BackgroundModifier) -> Bool { + a.background == b.background && a.alignment == b.alignment + } +} -// MARK: - View + Background [6.4.41] [WIP] +// MARK: - BackgroundStyleModifier + +@available(OpenSwiftUI_v3_0, *) +@frozen +public struct _BackgroundStyleModifier