diff --git a/Sources/HandySwiftUI/Modifiers/ValueChangeModifier.swift b/Sources/HandySwiftUI/Modifiers/ValueChangeModifier.swift new file mode 100644 index 0000000..602c1b5 --- /dev/null +++ b/Sources/HandySwiftUI/Modifiers/ValueChangeModifier.swift @@ -0,0 +1,20 @@ +import SwiftUI + +extension View { + /// Calls `action` with the new value whenever `value` changes, using the `onChange` variant that is not deprecated on the running OS. + /// + /// `onChange(of:perform:)` is deprecated starting with iOS 17 (and from the start on visionOS), while its replacement needs iOS 17, + /// one above the package's minimum. + @ViewBuilder + func onValueChange(of value: Value, perform action: @escaping (Value) -> Void) -> some View { + #if os(visionOS) + self.onChange(of: value) { _, newValue in action(newValue) } + #else + if #available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) { + self.onChange(of: value) { _, newValue in action(newValue) } + } else { + self.onChange(of: value, perform: action) + } + #endif + } +} diff --git a/Sources/HandySwiftUI/Types/Views/LimitedTextField.swift b/Sources/HandySwiftUI/Types/Views/LimitedTextField.swift index 0246ed1..c4dc1a9 100644 --- a/Sources/HandySwiftUI/Types/Views/LimitedTextField.swift +++ b/Sources/HandySwiftUI/Types/Views/LimitedTextField.swift @@ -21,7 +21,7 @@ public struct LimitedTextField: View { public var body: some View { VStack(alignment: .trailing, spacing: 4) { TextField(self.title, text: self.$text) - .onChange(of: self.text) { _ in + .onValueChange(of: self.text) { _ in if self.text.count > self.characterLimit { self.text = String(self.text.prefix(self.characterLimit)) }