From 69c28005720c3733413bfae3835c6e099015bb00 Mon Sep 17 00:00:00 2001 From: Muukii Date: Tue, 13 Aug 2024 22:24:20 +0200 Subject: [PATCH 1/2] Patch --- Sources/SwiftUISupport/ObjectEdge.swift | 117 ++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 Sources/SwiftUISupport/ObjectEdge.swift diff --git a/Sources/SwiftUISupport/ObjectEdge.swift b/Sources/SwiftUISupport/ObjectEdge.swift new file mode 100644 index 0000000000..3e28d891e4 --- /dev/null +++ b/Sources/SwiftUISupport/ObjectEdge.swift @@ -0,0 +1,117 @@ +import SwiftUI + +/** + https://forums.developer.apple.com/forums/thread/739163 + */ +@propertyWrapper +struct ObjectEdge: DynamicProperty { + + @State private var box: Box = .init() + + var wrappedValue: O { + if let value = box.value { + return value + } else { + box.value = factory() + return box.value! + } + } + + private let factory: () -> O + + init(wrappedValue factory: @escaping @autoclosure () -> O) { + self.factory = factory + } + + private final class Box { + var value: Value? + } + +} + +#if DEBUG + +@available(iOS 17, *) +@Observable +private final class Model { + + var count: Int = 0 + + init(count: Int) { + print("Init model") + self.count = count + } + + func up() { + count += 1 + } +} + +@available(iOS 17, *) +private struct Demo: View { + + @ObjectEdge var model: Model = .init(count: 0) + + var body: some View { + + VStack { + Text("\(model.count)") + Button("Up") { + model.up() + } + } + } +} + +@available(iOS 17, *)#Preview{ + Demo() +} + +struct Box { + + var value: T + + init(_ value: T) { + print("Init box") + self.value = value + } +} + +#Preview("State init value") { + + struct StateInit: View { + + @State var value: Box = .init(0) + + private let nested: () -> Nested + + init(@ViewBuilder nested: @escaping () -> Nested) { + self.nested = nested + } + + var body: some View { + VStack { + Text(value.value.description) + Button("Up") { + value.value += 1 + } + nested() + } + .padding() + .background( + RoundedRectangle(cornerRadius: 8) + .fill(Color.yellow.opacity(0.2)) + ) + } + } + + return StateInit { + StateInit { + StateInit { + EmptyView() + } + } + } +} + +#endif From fa898f038a262ecca379d08f726a1c63baeef685 Mon Sep 17 00:00:00 2001 From: Muukii Date: Tue, 13 Aug 2024 22:24:57 +0200 Subject: [PATCH 2/2] Update --- Sources/SwiftUISupport/ObjectEdge.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/SwiftUISupport/ObjectEdge.swift b/Sources/SwiftUISupport/ObjectEdge.swift index 3e28d891e4..36914a0a2d 100644 --- a/Sources/SwiftUISupport/ObjectEdge.swift +++ b/Sources/SwiftUISupport/ObjectEdge.swift @@ -4,11 +4,11 @@ import SwiftUI https://forums.developer.apple.com/forums/thread/739163 */ @propertyWrapper -struct ObjectEdge: DynamicProperty { +public struct ObjectEdge: DynamicProperty { @State private var box: Box = .init() - var wrappedValue: O { + public var wrappedValue: O { if let value = box.value { return value } else { @@ -19,7 +19,7 @@ struct ObjectEdge: DynamicProperty { private let factory: () -> O - init(wrappedValue factory: @escaping @autoclosure () -> O) { + public init(wrappedValue factory: @escaping @autoclosure () -> O) { self.factory = factory }