From 4192e24cbc72a260c6a8ed305fa4e7e6414a0007 Mon Sep 17 00:00:00 2001 From: "Tanabe, Alex" Date: Mon, 27 Jun 2022 20:57:07 +0900 Subject: [PATCH 1/2] Fixed the timing of updating the text binding on SwiftUITextField --- .../Source/UIKitViews/UIKitControls.swift | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Sources/AltSwiftUI/Source/UIKitViews/UIKitControls.swift b/Sources/AltSwiftUI/Source/UIKitViews/UIKitControls.swift index 8baa8b8..c57a30e 100644 --- a/Sources/AltSwiftUI/Source/UIKitViews/UIKitControls.swift +++ b/Sources/AltSwiftUI/Source/UIKitViews/UIKitControls.swift @@ -82,6 +82,9 @@ class SwiftUITextField: UITextField, UITextFieldDelegate, UIKitViewHandler { init() { super.init(frame: .zero) self.delegate = self + + addTarget(self, action: #selector(Self.textFieldDidChange(_:)), for: .editingChanged) + setupView() } required init?(coder: NSCoder) { @@ -143,9 +146,15 @@ class SwiftUITextField: UITextField, UITextFieldDelegate, UIKitViewHandler { let newText = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) if let text = newText, textBinding?.wrappedValue != text { lastWrittenText = text - setBindingText(text) } - return textBinding?.wrappedValue == newText + return true + } + + // MARK: Text change handling + + @objc func textFieldDidChange(_ textField: UITextField) { + guard let text = textField.text else { return } + setBindingText(text) } } From a9a4006e8bfc4105c311820b946d039a138590df Mon Sep 17 00:00:00 2001 From: "Tanabe, Alex" Date: Tue, 28 Jun 2022 10:38:15 +0900 Subject: [PATCH 2/2] Remove unnecessary logic and avoided sending consecutive text change events with the same value --- .../Source/UIKitViews/UIKitControls.swift | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/Sources/AltSwiftUI/Source/UIKitViews/UIKitControls.swift b/Sources/AltSwiftUI/Source/UIKitViews/UIKitControls.swift index c57a30e..7cc90c1 100644 --- a/Sources/AltSwiftUI/Source/UIKitViews/UIKitControls.swift +++ b/Sources/AltSwiftUI/Source/UIKitViews/UIKitControls.swift @@ -110,6 +110,10 @@ class SwiftUITextField: UITextField, UITextFieldDelegate, UIKitViewHandler { setContentCompressionResistancePriority(.defaultLow, for: .horizontal) } private func setBindingText(_ text: String) { + guard lastWrittenText != text else { return } + + lastWrittenText = textBinding?.wrappedValue ?? "" + if let value = value, let formatter = formatter { var object: AnyObject? formatter.getObjectValue(&object, for: text, errorDescription: nil) @@ -127,34 +131,20 @@ class SwiftUITextField: UITextField, UITextFieldDelegate, UIKitViewHandler { onCommit?() return true } + func textFieldDidBeginEditing(_ textField: UITextField) { firstResponder?.wrappedValue = true onEditingChanged?(true) } func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) { - // ios 12 will not call shouldChangeCharactersIn func when select word candidate. - // so make sure update binding text here - if let text = text, textBinding?.wrappedValue != text { - lastWrittenText = text - setBindingText(text) - } - firstResponder?.wrappedValue = false onEditingChanged?(false) } - func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { - let newText = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) - if let text = newText, textBinding?.wrappedValue != text { - lastWrittenText = text - } - return true - } // MARK: Text change handling @objc func textFieldDidChange(_ textField: UITextField) { - guard let text = textField.text else { return } - setBindingText(text) + setBindingText(textField.text ?? "") } } @@ -255,7 +245,7 @@ class SwiftUISegmentedControl: UISegmentedControl, UIKitViewHandler { @objc private func valueChanged() { selectionBinding.wrappedValue = selectedSegmentIndex - } + } } class SwiftUIDatePicker: UIDatePicker, UIKitViewHandler {