Skip to content

Commit fb017de

Browse files
authored
Add onChange modifier support (#413)
* Add ValueActionModifier implementation * Add ValueActionModifierExample * Fix onChange implementation issue * Add ValueActionModifierCompatibilityTests * Fix DeprecatedDeclaration werror
1 parent d6e83c4 commit fb017de

File tree

10 files changed

+917
-40
lines changed

10 files changed

+917
-40
lines changed

Example/HostingExample/ViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,6 @@ class ViewController: NSViewController {
6666

6767
struct ContentView: View {
6868
var body: some View {
69-
ColorAnimationExample()
69+
ValueActionModifierExample()
7070
}
7171
}

Example/SharedExample/Animation/ColorAnimationExample.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
//
22
// ColorAnimationExample.swift
33
// SharedExample
4-
//
5-
// Created by Kyle on 2025/7/20.
6-
//
4+
75
#if OPENSWIFTUI
86
import OpenSwiftUI
97
#else

Example/SharedExample/View/AppearanceActionModifierExample.swift renamed to Example/SharedExample/ViewModifier/AppearanceActionModifierExample.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import OpenSwiftUI
77
#else
88
import SwiftUI
99
#endif
10-
import Foundation
1110

1211
struct AppearanceActionModifierExample: View {
1312
@State private var first = true
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// ValueActionModifier.swift
3+
// SharedExample
4+
5+
#if OPENSWIFTUI
6+
import OpenSwiftUI
7+
#else
8+
import SwiftUI
9+
#endif
10+
11+
struct ValueActionModifierExample: View {
12+
@State private var value = 0
13+
var body: some View {
14+
Color.red
15+
.onAppear {
16+
value = 1
17+
DispatchQueue.main.async {
18+
value = 2
19+
}
20+
}
21+
.onChange(of: value) { newValue in
22+
print(newValue)
23+
}
24+
}
25+
}

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ var sharedSwiftSettings: [SwiftSetting] = [
5858
.enableUpcomingFeature("BareSlashRegexLiterals"),
5959
.enableUpcomingFeature("InternalImportsByDefault"),
6060
.enableUpcomingFeature("InferSendableFromCaptures"),
61+
.unsafeFlags(["-Wwarning", "DeprecatedDeclaration"]), // We want to use deprecated APIs in test targets
6162
.define("OPENSWIFTUI_SUPPRESS_DEPRECATED_WARNINGS"),
6263
// FIXME: -unavailable-decl-optimization=stub is not working somehow (eg. Color.vibrancy). Dig into this later
6364
.unsafeFlags(["-unavailable-decl-optimization=stub"]),
@@ -136,7 +137,6 @@ if warningsAsErrorsCondition {
136137
// items we want to ignore:
137138
// [error_from_clang] [error_in_future_swift_version]
138139
// sharedSwiftSettings.append(.unsafeFlags(["-warnings-as-errors"]))
139-
sharedSwiftSettings.append(.unsafeFlags(["-Werror", "DeprecatedDeclaration"]))
140140
sharedSwiftSettings.append(.unsafeFlags(["-Werror", "Unsafe"]))
141141
sharedSwiftSettings.append(.unsafeFlags(["-Werror", "UnknownWarningGroup"]))
142142
sharedSwiftSettings.append(.unsafeFlags(["-Werror", "ExistentialAny"]))
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//
2+
// ValueActionSceneModifier.swift
3+
// OpenSwiftUI
4+
//
5+
// Audited for 6.5.4
6+
// Status: WIP
7+
8+
package import OpenSwiftUICore
9+
10+
@available(OpenSwiftUI_v2_0, *)
11+
extension Scene {
12+
@available(*, deprecated, message: "Use `onChange` with a two or zero parameter action closure instead.")
13+
@inlinable
14+
nonisolated public func onChange<V>(
15+
of value: V,
16+
perform action: @escaping (_ newValue: V) -> Void
17+
) -> some Scene where V: Equatable {
18+
// modifier(_ValueActionModifier(value: value, action: action))
19+
return self
20+
}
21+
}
22+
23+
@available(OpenSwiftUI_v2_0, *)
24+
extension _ValueActionModifier: _SceneModifier {
25+
@MainActor
26+
@preconcurrency
27+
public static func _makeScene(
28+
modifier: _GraphValue<_ValueActionModifier<Value>>,
29+
inputs: _SceneInputs,
30+
body: @escaping (_Graph, _SceneInputs) -> _SceneOutputs
31+
) -> _SceneOutputs {
32+
_openSwiftUIUnimplementedFailure()
33+
}
34+
}
35+
36+
@available(OpenSwiftUI_v5_0, *)
37+
extension Scene {
38+
nonisolated public func onChange<V>(
39+
of value: V,
40+
initial: Bool = false,
41+
_ action: @escaping (_ oldValue: V, _ newValue: V) -> Void
42+
) -> some Scene where V: Equatable {
43+
_openSwiftUIUnimplementedFailure()
44+
}
45+
46+
nonisolated public func onChange<V>(
47+
of value: V,
48+
initial: Bool = false,
49+
_ action: @escaping () -> Void
50+
) -> some Scene where V: Equatable {
51+
_openSwiftUIUnimplementedFailure()
52+
}
53+
}

Sources/OpenSwiftUICore/Modifier/ViewModifier/ValueActionChangeModifier.swift

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)