Skip to content

Commit 0538d79

Browse files
committed
Stamp trees produced under withAnimation
1 parent 0f73ee9 commit 0538d79

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

AndroidSwiftUICore/Sources/AndroidSwiftUICore/ViewHost.swift

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,17 @@ public final class ViewHost: @unchecked Sendable {
2626
/// result across the bridge; tests read `evaluate()` directly instead.
2727
public var onStateChange: (() -> Void)?
2828

29+
/// The animation captured from the transaction at write time, carried to
30+
/// the (coalesced) evaluation the write scheduled.
31+
private var pendingAnimation: Animation?
32+
2933
public init(_ root: any View, reflector: StateReflector = MirrorStateReflector()) {
3034
self.root = root
3135
self.storage = StateStorage(reflector: reflector)
3236
self.storage.onChange = { [weak self] in
37+
if let animation = Transaction._current {
38+
self?.pendingAnimation = animation
39+
}
3340
self?.onStateChange?()
3441
}
3542
}
@@ -43,13 +50,24 @@ public final class ViewHost: @unchecked Sendable {
4350
// Track @Observable reads during evaluation: a later mutation of any
4451
// observed property schedules a re-evaluation, exactly like a @State
4552
// write. Re-arms itself because the change handler triggers evaluate().
46-
return withObservationTracking {
53+
var node = withObservationTracking {
4754
Evaluator.resolve(root, context)
4855
} onChange: { [weak self] in
56+
if let animation = Transaction._current {
57+
self?.pendingAnimation = animation
58+
}
4959
self?.onStateChange?()
5060
}
5161
#else
52-
return Evaluator.resolve(root, context)
62+
var node = Evaluator.resolve(root, context)
5363
#endif
64+
// A tree produced by a withAnimation write carries the animation on its
65+
// root; the interpreter eases changed modifier values while it applies.
66+
if let animation = pendingAnimation {
67+
pendingAnimation = nil
68+
node.props["animationCurve"] = .string(animation.curve)
69+
node.props["animationDurationMs"] = .double(animation.duration * 1000)
70+
}
71+
return node
5472
}
5573
}

0 commit comments

Comments
 (0)