Skip to content

Commit 15ce5b0

Browse files
committed
Add TransactionAnimation and move folder
1 parent d61186f commit 15ce5b0

17 files changed

+157
-42
lines changed

Sources/OpenSwiftUICore/Data/Transaction/Transaction+Animation.swift

Lines changed: 0 additions & 42 deletions
This file was deleted.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//
2+
// TransactionAnimation.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for iOS 18.0
6+
// Status: Complete
7+
// ID: 39EC6D46662E6D7A6963F5C611934B0A (SwiftUI)
8+
// ID: D98E9A1069CEEADA58829ED440E36F30 (SwiftUICore)
9+
10+
extension Transaction {
11+
/// Creates a transaction and assigns its animation property.
12+
///
13+
/// - Parameter animation: The animation to perform when the current state
14+
/// changes.
15+
public init(animation: Animation?) {
16+
self.init()
17+
self.animation = animation
18+
}
19+
20+
/// The animation, if any, associated with the current state change.
21+
public var animation: Animation? {
22+
get { self[AnimationKey.self] }
23+
set { self[AnimationKey.self] = newValue }
24+
}
25+
26+
package var effectiveAnimation: Animation? {
27+
animation ?? (tracksVelocity ? .velocityTracking : nil)
28+
}
29+
30+
package var _animationFrameInterval: Double? {
31+
get { self[AnimationFrameIntervalKey.self] }
32+
set { self[AnimationFrameIntervalKey.self] = newValue }
33+
}
34+
35+
package var _animationReason: UInt32? {
36+
get { self[AnimationReasonKey.self] }
37+
set { self[AnimationReasonKey.self] = newValue }
38+
}
39+
40+
package var isAnimated: Bool {
41+
guard let animation,
42+
!disablesAnimations else {
43+
return false
44+
}
45+
return true
46+
}
47+
48+
/// A Boolean value that indicates whether views should disable animations.
49+
///
50+
/// This value is `true` during the initial phase of a two-part transition
51+
/// update, to prevent ``View/animation(_:)`` from inserting new animations
52+
/// into the transaction.
53+
public var disablesAnimations: Bool {
54+
get { self[DisablesAnimationsKey.self] }
55+
set { self[DisablesAnimationsKey.self] = newValue }
56+
}
57+
58+
package var disablesContentTransitions: Bool {
59+
get { self[DisablesContentTransactionKey.self] }
60+
set { self[DisablesContentTransactionKey.self] = newValue }
61+
}
62+
63+
package mutating func disableAnimations() {
64+
animation = nil
65+
disablesAnimations = true
66+
}
67+
68+
package var animationIgnoringTransitionPhase: Animation? {
69+
guard disablesAnimations else {
70+
return animation
71+
}
72+
var result: Animation?
73+
forEach(keyType: AnimationKey.self) { animation, stop in
74+
guard let animation else {
75+
return
76+
}
77+
result = animation
78+
stop = true
79+
}
80+
return result
81+
}
82+
}
83+
84+
private struct AnimationKey: TransactionKey {
85+
static var defaultValue: Animation? { nil }
86+
}
87+
88+
private struct DisablesAnimationsKey: TransactionKey {
89+
static var defaultValue: Bool { false }
90+
}
91+
92+
private struct AnimationFrameIntervalKey: TransactionKey {
93+
static var defaultValue: Double? { nil }
94+
}
95+
96+
private struct AnimationReasonKey: TransactionKey {
97+
static var defaultValue: UInt32? { nil }
98+
}
99+
100+
private struct DisablesContentTransactionKey: TransactionKey {
101+
static var defaultValue: Bool { false }
102+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//
2+
// VelocityTrackingAnimation.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for iOS 18.0
6+
// Status: WIP
7+
// ID: FD9125BC1E04E33D1D7BE4A31225AA98 (SwiftUICore)
8+
9+
// MARK: - TracksVelocityKey
10+
11+
private struct TracksVelocityKey: TransactionKey {
12+
static var defaultValue: Bool { false }
13+
}
14+
15+
extension Transaction {
16+
/// Whether this transaction will track the velocity of any animatable
17+
/// properties that change.
18+
///
19+
/// This property can be enabled in an interactive context to track velocity
20+
/// during a user interaction so that when the interaction ends, an
21+
/// animation can use the accumulated velocities to create animations that
22+
/// preserve them. This tracking is mutually exclusive with an animation
23+
/// being used during a view change, since if there is an animation, it is
24+
/// responsible for managing its own velocity.
25+
///
26+
/// Gesture onChanged and updating callbacks automatically set this property
27+
/// to true.
28+
///
29+
/// This example shows an interaction which applies changes, tracking
30+
/// velocity until the final change, which applies an animation (which will
31+
/// start with the velocity that was tracked during the previous changes).
32+
/// These changes could come from a server or from an interactive control
33+
/// like a slider.
34+
///
35+
/// func receiveChange(change: ChangeInfo) {
36+
/// var transaction = Transaction()
37+
/// if change.isFinal {
38+
/// transaction.animation = .spring
39+
/// } else {
40+
/// transaction.tracksVelocity = true
41+
/// }
42+
/// withTransaction(transaction) {
43+
/// state.applyChange(change)
44+
/// }
45+
/// }
46+
public var tracksVelocity: Bool {
47+
get { self[TracksVelocityKey.self] }
48+
set { self[TracksVelocityKey.self] = newValue }
49+
}
50+
}
51+
52+
extension Animation {
53+
// FIXME: VelocityTrackingAnimation
54+
static let velocityTracking: Animation = Animation()
55+
}

0 commit comments

Comments
 (0)