Skip to content

Commit 2d2925d

Browse files
committed
Update package
1 parent a1cf3ab commit 2d2925d

File tree

4 files changed

+82
-5
lines changed

4 files changed

+82
-5
lines changed

Sources/Intermodular/Helpers/SwiftUI/LazyView.swift

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public struct LazyAppearViewProxy {
4646

4747
/// A view that appears lazily.
4848
public struct LazyAppearView<Content: View>: View {
49-
private let destination: (LazyAppearViewProxy) -> Content
49+
private let destination: (LazyAppearViewProxy) -> AnyView
5050
private let debounceInterval: DispatchTimeInterval?
5151
private let explicitAnimation: Animation?
5252
private let disableAnimations: Bool
@@ -60,7 +60,25 @@ public struct LazyAppearView<Content: View>: View {
6060
animation: Animation,
6161
@ViewBuilder destination: @escaping (LazyAppearViewProxy) -> Content
6262
) {
63-
self.destination = destination
63+
self.destination = { destination($0).eraseToAnyView() }
64+
self.debounceInterval = debounceInterval
65+
self.explicitAnimation = animation
66+
self.disableAnimations = false
67+
}
68+
69+
public init(
70+
debounceInterval: DispatchTimeInterval? = nil,
71+
animation: Animation,
72+
@ViewBuilder destination: @escaping () -> Content
73+
) {
74+
self.destination = { proxy in
75+
Group {
76+
if proxy.appearance == .active {
77+
destination()
78+
}
79+
}
80+
.eraseToAnyView()
81+
}
6482
self.debounceInterval = debounceInterval
6583
self.explicitAnimation = animation
6684
self.disableAnimations = false
@@ -71,7 +89,25 @@ public struct LazyAppearView<Content: View>: View {
7189
disableAnimations: Bool = false,
7290
@ViewBuilder destination: @escaping (LazyAppearViewProxy) -> Content
7391
) {
74-
self.destination = destination
92+
self.destination = { destination($0).eraseToAnyView() }
93+
self.debounceInterval = debounceInterval
94+
self.explicitAnimation = nil
95+
self.disableAnimations = disableAnimations
96+
}
97+
98+
public init(
99+
debounceInterval: DispatchTimeInterval? = nil,
100+
disableAnimations: Bool = false,
101+
@ViewBuilder destination: @escaping () -> Content
102+
) {
103+
self.destination = { proxy in
104+
Group {
105+
if proxy.appearance == .active {
106+
destination()
107+
}
108+
}
109+
.eraseToAnyView()
110+
}
75111
self.debounceInterval = debounceInterval
76112
self.explicitAnimation = nil
77113
self.disableAnimations = disableAnimations

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,16 @@ public func withoutAnimation(_ flag: Bool = true, _ body: () -> ()) {
5252

5353
public func withAnimation(
5454
_ animation: Animation = .default,
55-
after delay: DispatchTimeInterval,
55+
after delay: DispatchTimeInterval?,
5656
body: @escaping () -> Void
5757
) {
58-
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
58+
if let delay = delay {
59+
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
60+
withAnimation(animation) {
61+
body()
62+
}
63+
}
64+
} else {
5965
withAnimation(animation) {
6066
body()
6167
}

Sources/Intramodular/Appearance/VisibilityModifier.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,13 @@ extension View {
3131
public func visible(_ isVisible: Bool = true) -> some View {
3232
modifier(_VisibilityModifier(isVisible: isVisible))
3333
}
34+
35+
/// Sets a view's visibility.
36+
///
37+
/// The view still retains its frame.
38+
@inlinable
39+
public func visible(_ isVisible: Bool, animation: Animation?) -> some View {
40+
modifier(_VisibilityModifier(isVisible: isVisible))
41+
.animation(animation, value: isVisible)
42+
}
3443
}

Sources/Intramodular/Dynamic Properties/ObservedValue.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,29 @@ extension ObservedValue {
5454
self.init(ObservableValueRoot(root: value))
5555
}
5656
}
57+
58+
extension View {
59+
public func modify<T, TransformedView: View>(
60+
observing storage: ViewStorage<T>,
61+
transform: @escaping (AnyView, T) -> TransformedView
62+
) -> some View {
63+
WithObservedValue(value: .init(storage), content: { transform(AnyView(self), $0) })
64+
}
65+
66+
public func modify<T: Hashable, TransformedView: View>(
67+
observing storage: ViewStorage<T>,
68+
transform: @escaping (AnyView) -> TransformedView
69+
) -> some View {
70+
WithObservedValue(value: .init(storage), content: { transform(AnyView(self.background(EmptyView().id($0)))) })
71+
}
72+
}
73+
74+
private struct WithObservedValue<T, Content: View>: View {
75+
@ObservedValue var value: T
76+
77+
let content: (T) -> Content
78+
79+
var body: some View {
80+
content(value)
81+
}
82+
}

0 commit comments

Comments
 (0)