I have created a wrapped NSTextField to allow for keystroke validation.
My problem is that I am setting the bankBalance property on the Person and the Text next to the TextField is being updated but my CurrencyTextField is not.
I may have 30 years of programming experience, including quite a few with Swift but SwiftUI, beyond the simplest of examples, is proving a bit difficult. What am I missing here please?
Code Block Swift class ValidatableTextField: NSTextField, NSTextViewDelegate { var validationClosure: ((ValidatableTextField, NSRange, String?) -> Bool)? func textView(_ textView: NSTextView, shouldChangeTextIn affectedCharRange: NSRange, replacementString: String?) -> Bool { return validationClosure?(self, affectedCharRange, replacementString) ?? true } } struct CurrencyTextField<rootT : AnyObject, valueT> : NSViewRepresentable { private var object: rootT? private var keyPath: ReferenceWritableKeyPath<rootT, valueT>? func makeCoordinator() -> Coordinator { return Coordinator(object, keyPath: keyPath) } init(object: rootT?, keyPath: ReferenceWritableKeyPath<rootT, valueT>?) { self.object = object self.keyPath = keyPath } func makeNSView(context: Context) -> ValidatableTextField { let textField = ValidatableTextField() textField.validationClosure = context.coordinator.validationClosure return textField } func updateNSView(_ nsView: ValidatableTextField, context: Context) { guard let object = object, let keyPath = keyPath else { return } nsView.stringValue = "\(object[keyPath: keyPath])" } class Coordinator : NSObject { var object: rootT? var keyPath: ReferenceWritableKeyPath<rootT, valueT>? init(_ object: rootT?, keyPath: ReferenceWritableKeyPath<rootT, valueT>?) { self.object = object self.keyPath = keyPath } lazy var validationClosure: ((ValidatableTextField, NSRange, String?) -> Bool) = { textField, range, replacementString in if replacementString!.isEmpty { return true } return replacementString?.contains(where: { (char: Character) -> Bool in return char.isNumber || String(char) == Locale.autoupdatingCurrent.decimalSeparator }) ?? false } } } struct ContentView: View { @ObservedObject var person: Person var body: some View { VStack { Spacer() Text(person.name) HStack { Spacer(minLength: 100) CurrencyTextField<Person, Double>(object: person, keyPath: \.bankBalance) Text("\(person.bankBalance)") Spacer(minLength: 100) } Button(action: { self.person.bankBalance = 65.43 }) { Text("Change bank balance") } Spacer() } } }
My problem is that I am setting the bankBalance property on the Person and the Text next to the TextField is being updated but my CurrencyTextField is not.
I may have 30 years of programming experience, including quite a few with Swift but SwiftUI, beyond the simplest of examples, is proving a bit difficult. What am I missing here please?