From d5917750f41ef38d92adb0a001d342839920a87a Mon Sep 17 00:00:00 2001 From: Pavel Holec Date: Wed, 13 Dec 2023 13:03:01 +0100 Subject: [PATCH 1/2] Update keyboard dismissal in inputFieldShouldReturn --- .../TextFields/TextFieldCoordinator.swift | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Sources/Orbit/Support/TextFields/TextFieldCoordinator.swift b/Sources/Orbit/Support/TextFields/TextFieldCoordinator.swift index 5dcdd7d5222..76c5953ae63 100644 --- a/Sources/Orbit/Support/TextFields/TextFieldCoordinator.swift +++ b/Sources/Orbit/Support/TextFields/TextFieldCoordinator.swift @@ -126,7 +126,8 @@ public final class TextFieldCoordinator: NSObject, ObservableObject { if shouldReturn { DispatchQueue.main.async { - textInput.textInputView?.superview?.resignFirstResponder() + textInput.resignFirstResponder() + self.inputFieldReturnAction() if let identifier = self.identifier { @@ -299,4 +300,22 @@ extension UITextInput { replace(textRange, withText: newValue) } } + + /// Attempt to dismiss the keyboard. + /// Setting the @FocusState to nil in a call site has the same effect. + func resignFirstResponder() { + var attempts = 2 + var view: UIView? = textInputView + + while attempts > 0 { + guard let superview = view?.superview else { return } + + if superview.resignFirstResponder() { + return + } + + view = superview + attempts -= 1 + } + } } From 7c4244380b9218e179619d03185a0755672c04c5 Mon Sep 17 00:00:00 2001 From: Pavel Holec Date: Wed, 13 Dec 2023 13:46:25 +0100 Subject: [PATCH 2/2] Update documentation related to identifier() and inputFieldReturnAction --- Sources/Orbit/Components/SegmentedSwitch.swift | 2 +- Sources/Orbit/Components/Tabs.swift | 2 +- .../InputFieldBeginEditingActionKey.swift | 2 +- .../InputFieldEndEditingActionKey.swift | 2 +- .../InputFieldReturnActionKey.swift | 2 +- ...tFieldShouldChangeCharactersActionKey.swift | 2 +- .../InputFieldShouldReturnActionKey.swift | 18 +++++++++++++++--- 7 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Sources/Orbit/Components/SegmentedSwitch.swift b/Sources/Orbit/Components/SegmentedSwitch.swift index fbd4f8b51fe..a9a51b2abfe 100644 --- a/Sources/Orbit/Components/SegmentedSwitch.swift +++ b/Sources/Orbit/Components/SegmentedSwitch.swift @@ -4,7 +4,7 @@ import SwiftUI /// A counterpart of the native `SwiftUI.Picker` with `segmented` style applied. /// /// A ``SegmentedSwitch`` consists of a label and two or three choices. -/// Each choice must be given an Orbit `identifier` that matches a value of the selection binding: +/// Each choice must be given an Orbit ``identifier(_:)`` that matches a value of the selection binding: /// /// ```swift /// enum Direction { diff --git a/Sources/Orbit/Components/Tabs.swift b/Sources/Orbit/Components/Tabs.swift index e8b6bca6f4d..afa21e3a6e2 100644 --- a/Sources/Orbit/Components/Tabs.swift +++ b/Sources/Orbit/Components/Tabs.swift @@ -4,7 +4,7 @@ import SwiftUI /// A counterpart of the native `SwiftUI.Picker` with `segmented` style applied. A typical use case is switching between tabs in a native `SwiftUI.TabView`. /// /// A ``Tabs`` consists of labels that represent specific tabs. -/// Each tab label must be given an Orbit `identifier` that matches a value of the selection binding: +/// Each tab label must be given an Orbit ``identifier(_:)`` that matches a value of the selection binding: /// /// ```swift /// Tabs(selection: $selectedTab) { diff --git a/Sources/Orbit/Support/Environment Keys/InputFieldBeginEditingActionKey.swift b/Sources/Orbit/Support/Environment Keys/InputFieldBeginEditingActionKey.swift index 0953324523b..a387f4471ef 100644 --- a/Sources/Orbit/Support/Environment Keys/InputFieldBeginEditingActionKey.swift +++ b/Sources/Orbit/Support/Environment Keys/InputFieldBeginEditingActionKey.swift @@ -38,7 +38,7 @@ public extension View { /// Set the `textFieldDidBeginEditing` action for Orbit identifiable text fields. /// - /// Mark the associated Orbit text field with `identifier()` modifier to set its identity. + /// - Important: Mark the associated Orbit text field with ``identifier(_:)`` modifier to set its identity. /// /// - Parameters: /// - action: A handler that is executed when the user starts editing an identifiable text field inside the view hierarchy. diff --git a/Sources/Orbit/Support/Environment Keys/InputFieldEndEditingActionKey.swift b/Sources/Orbit/Support/Environment Keys/InputFieldEndEditingActionKey.swift index 2c4ae904d2a..23ecc8a1548 100644 --- a/Sources/Orbit/Support/Environment Keys/InputFieldEndEditingActionKey.swift +++ b/Sources/Orbit/Support/Environment Keys/InputFieldEndEditingActionKey.swift @@ -38,7 +38,7 @@ public extension View { /// Set the `textFieldDidEndEditing` action for Orbit identifiable text fields. /// - /// Mark the associated Orbit text field with `identifier()` modifier to set its identity. + /// - Important: Mark the associated Orbit text field with ``identifier(_:)`` modifier to set its identity. /// /// - Parameters: /// - action: A handler that is executed after the user ends editing a specific identifiable text field inside the view hierarchy. diff --git a/Sources/Orbit/Support/Environment Keys/InputFieldReturnActionKey.swift b/Sources/Orbit/Support/Environment Keys/InputFieldReturnActionKey.swift index 6c71e9833ec..ecda913259e 100644 --- a/Sources/Orbit/Support/Environment Keys/InputFieldReturnActionKey.swift +++ b/Sources/Orbit/Support/Environment Keys/InputFieldReturnActionKey.swift @@ -35,7 +35,7 @@ public extension View { /// Set the `textFieldReturn` action for Orbit identifiable text fields. /// - /// Mark the associated Orbit text field with `identifier()` modifier to set its identity. + /// - Important: Mark the associated Orbit text field with ``identifier(_:)`` modifier to set its identity. /// /// - Parameters: /// - action: A handler that is executed immediately after keyboard Return action for the identifiable text field inside the view hierarchy. diff --git a/Sources/Orbit/Support/Environment Keys/InputFieldShouldChangeCharactersActionKey.swift b/Sources/Orbit/Support/Environment Keys/InputFieldShouldChangeCharactersActionKey.swift index af91ac9aa11..66c3247d543 100644 --- a/Sources/Orbit/Support/Environment Keys/InputFieldShouldChangeCharactersActionKey.swift +++ b/Sources/Orbit/Support/Environment Keys/InputFieldShouldChangeCharactersActionKey.swift @@ -37,7 +37,7 @@ public extension View { /// Set the `textField(shouldChangeCharactersIn:)` action for Orbit identifiable text fields. /// - /// Mark the associated Orbit text field with `identifier()` modifier to set its identity. + /// - Important: Mark the associated Orbit text field with ``identifier(_:)`` modifier to set its identity. /// /// - Parameters: /// - action: A handler that is executed for identifiable text fields inside the view hierarchy when deciding whether to change the specified text. diff --git a/Sources/Orbit/Support/Environment Keys/InputFieldShouldReturnActionKey.swift b/Sources/Orbit/Support/Environment Keys/InputFieldShouldReturnActionKey.swift index b08cc11b01b..ecef24aa59d 100644 --- a/Sources/Orbit/Support/Environment Keys/InputFieldShouldReturnActionKey.swift +++ b/Sources/Orbit/Support/Environment Keys/InputFieldShouldReturnActionKey.swift @@ -25,7 +25,13 @@ public extension EnvironmentValues { public extension View { - /// Set the `textFieldShouldReturn` action for Orbit text fields. + /// Set the `textFieldShouldReturn` action for Orbit text fields that decides whether to process the keyboard Return button. + /// + /// By default, pressing the Return button will be processed and the keyboard will be dismissed, + /// triggering the optional ``inputFieldReturnAction(_:)-9w13u`` after the processing. + /// + /// If the Return button should be ignored instead, return `false` from the provided action. + /// If the focus should be switched to another field, modify the focus value in the provided action. /// /// - Parameters: /// - action: A handler that is executed to ask whether to process the pressing of the Return button for text fields inside the view hierarchy. @@ -33,9 +39,15 @@ public extension View { environment(\.inputFieldShouldReturnAction, action) } - /// Set the `textFieldShouldReturn` action for Orbit identifiable text fields. + /// Set the `textFieldShouldReturn` action for Orbit identifiable text fields that decides whether to process the keyboard Return button. + /// + /// By default, pressing the Return button will be processed and the keyboard will be dismissed, + /// triggering the optional ``inputFieldReturnAction(_:)-1mvv4`` after the processing. + /// + /// If the Return button should be ignored instead, return `false` from the provided action. + /// If the focus should be switched to another field, modify the focus value in the provided action. /// - /// Mark the associated Orbit text field with `identifier()` modifier to set its identity. + /// - Important: Mark the associated Orbit text field with ``identifier(_:)`` modifier to set its identity. /// /// - Parameters: /// - action: A handler that is executed to ask whether to process the pressing of the Return button for the identifiable text field inside the view hierarchy.