Skip to content

Commit 681ab42

Browse files
committed
Update package
1 parent 2d2925d commit 681ab42

File tree

4 files changed

+94
-28
lines changed

4 files changed

+94
-28
lines changed

Sources/Intermodular/Helpers/SwiftUI/DynamicProperty+.swift

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,35 @@
55
import Swift
66
import SwiftUI
77

8+
public func withInlineState<Value, Content: View>(
9+
initialValue: Value,
10+
@ViewBuilder content: @escaping (Binding<Value>) -> Content
11+
) -> some View {
12+
WithInlineState(initialValue: initialValue, content: content)
13+
}
14+
15+
public func withInlineObservedObject<Object: ObservableObject, Content: View>(
16+
_ object: Object,
17+
@ViewBuilder content: (Object) -> Content
18+
) -> some View {
19+
WithInlineObservedObject(object: object, content: content(object))
20+
}
21+
22+
public func withInlineObservedObject<Object: ObservableObject, Content: View>(
23+
_ object: Object?,
24+
@ViewBuilder content: (Object?) -> Content
25+
) -> some View {
26+
WithOptionalInlineObservedObject(object: .init(wrappedValue: object), content: content(object))
27+
}
28+
29+
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
30+
public func withInlineStateObject<Object: ObservableObject, Content: View>(
31+
_ object: @autoclosure @escaping () -> Object,
32+
@ViewBuilder content: @escaping (Object) -> Content
33+
) -> some View {
34+
WithInlineStateObject(object(), content: content)
35+
}
36+
837
private struct WithInlineState<Value, Content: View>: View {
938
@State var value: Value
1039

@@ -25,7 +54,17 @@ private struct WithInlineState<Value, Content: View>: View {
2554

2655
private struct WithInlineObservedObject<Object: ObservableObject, Content: View>: View {
2756
@ObservedObject var object: Object
57+
58+
let content: Content
59+
60+
var body: some View {
61+
content
62+
}
63+
}
2864

65+
private struct WithOptionalInlineObservedObject<Object: ObservableObject, Content: View>: View {
66+
@OptionalObservedObject var object: Object?
67+
2968
let content: Content
3069

3170
var body: some View {
@@ -51,25 +90,3 @@ private struct WithInlineStateObject<Object: ObservableObject, Content: View>: V
5190
content(object)
5291
}
5392
}
54-
55-
public func withInlineState<Value, Content: View>(
56-
initialValue: Value,
57-
@ViewBuilder content: @escaping (Binding<Value>) -> Content
58-
) -> some View {
59-
WithInlineState(initialValue: initialValue, content: content)
60-
}
61-
62-
public func withInlineObservedObject<Object: ObservableObject, Content: View>(
63-
_ object: Object,
64-
@ViewBuilder content: (Object) -> Content
65-
) -> some View {
66-
WithInlineObservedObject(object: object, content: content(object))
67-
}
68-
69-
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
70-
public func withInlineStateObject<Object: ObservableObject, Content: View>(
71-
_ object: @autoclosure @escaping () -> Object,
72-
@ViewBuilder content: @escaping (Object) -> Content
73-
) -> some View {
74-
WithInlineStateObject(object(), content: content)
75-
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// Copyright (c) Vatsal Manot
3+
//
4+
5+
import Swift
6+
import SwiftUI
7+
8+
private struct PredicatedAnimateOnChange<Value: Equatable>: ViewModifier {
9+
let animation: Animation?
10+
let value: Value
11+
let predicate: ((oldValue: Value, newValue: Value)) -> Bool
12+
13+
@ViewStorage private var lastValue: Value?
14+
15+
func body(content: Content) -> some View {
16+
content.transaction { view in
17+
if let oldValue = lastValue {
18+
if predicate((oldValue, value)) {
19+
view.animation = animation
20+
}
21+
}
22+
}
23+
}
24+
}
25+
26+
extension View {
27+
public func predicatedAnimation<Value: Equatable>(
28+
_ animation: Animation?,
29+
value: Value,
30+
predicate: @escaping ((oldValue: Value, newValue: Value)) -> Bool
31+
) -> some View {
32+
modifier(PredicatedAnimateOnChange(animation: animation, value: value, predicate: predicate))
33+
}
34+
}

Sources/Intramodular/Dynamic Properties/ObservedValue.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ extension View {
6363
WithObservedValue(value: .init(storage), content: { transform(AnyView(self), $0) })
6464
}
6565

66+
public func modify<T, TransformedView: View>(
67+
observing storage: ViewStorage<T>?,
68+
transform: @escaping (AnyView, T?) -> TransformedView
69+
) -> some View {
70+
WithOptionalObservableValue(value: .init(wrappedValue: storage.map(ObservedValue.init)?.base), content: { transform(AnyView(self), $0) })
71+
}
72+
6673
public func modify<T: Hashable, TransformedView: View>(
6774
observing storage: ViewStorage<T>,
6875
transform: @escaping (AnyView) -> TransformedView
@@ -71,6 +78,8 @@ extension View {
7178
}
7279
}
7380

81+
// MARK: - Auxiliary Implementation -
82+
7483
private struct WithObservedValue<T, Content: View>: View {
7584
@ObservedValue var value: T
7685

@@ -80,3 +89,13 @@ private struct WithObservedValue<T, Content: View>: View {
8089
content(value)
8190
}
8291
}
92+
93+
private struct WithOptionalObservableValue<T, Content: View>: View {
94+
@OptionalObservedObject var value: ObservableValue<T>?
95+
96+
let content: (T?) -> Content
97+
98+
var body: some View {
99+
content(value?.wrappedValue)
100+
}
101+
}

Sources/Intramodular/Dynamic Properties/OptionalObservedObject.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,10 @@ public struct OptionalObservedObject<ObjectType: ObservableObject>: DynamicPrope
2525
}
2626

2727
/// Initialize with the provided initial value.
28-
public init(wrappedValue value: ObjectType?) {
28+
public init(wrappedValue value: ObjectType? = nil) {
2929
self.base = value
3030
}
31-
32-
public init() {
33-
self.init(wrappedValue: nil)
34-
}
35-
31+
3632
public mutating func update() {
3733
_observedContainer.update()
3834
}

0 commit comments

Comments
 (0)