Skip to content

Commit 46bb921

Browse files
authored
fix: reset shouldIgnoreKeyboardEvents to false on resignFirstResponder (#996)
## 📜 Description Fixed missing keyboard events after dismissing a screen from native-stack via interactive gesture + using `KeyboardGestureArea`. ## 💡 Motivation and Context The problem happens because of this code: ```swift guard !KeyboardEventsIgnorer.shared.shouldIgnore else { KeyboardEventsIgnorer.shared.shouldIgnoreKeyboardEvents = false return } ``` This code filters out a subsequent event when we attach `InvisibleAccessoryView`. When we call `resignFirstResponder` we call: ```swift public func hide() { if isVisible { NotificationCenter.default.post( name: .shouldIgnoreKeyboardEvents, object: nil, userInfo: ["ignore": true] ) currentInputAccessoryView?.hide() } } ``` Because we detach the `InvisibleAccessoryView` and it'll trigger `keyboardDidAppear` event too. And it works well for plain dismissal (tap-to-dismiss) or after interactive dismissal. But in native-stack when you do a swipe-left-to-dismiss-screen the keyboard is associated with the screen and we will not get additional `keyboardDidAppear` event, so `shouldIgnore` field will be always `true`. And will be reset only when keyboard gets shown again. To solve that problem I decided to add the code: ```swift NotificationCenter.default.post( name: .shouldIgnoreKeyboardEvents, object: nil, userInfo: ["ignore": false] ) ``` That will be triggered before a call to original `resignFirstResponder`. I tested 3 scenarios: - tap to dismiss; - interactive swipe to dismiss; - swipe screen to dismiss. And all of them work without any regressions, so I think it's safe to have this code and automatically reset the flag when the view gets detached 🤞 ## 📢 Changelog <!-- High level overview of important changes --> <!-- For example: fixed status bar manipulation; added new types declarations; --> <!-- If your changes don't affect one of platform/language below - then remove this platform/language --> ### iOS - reset `shouldIgnoreKeyboardEvents` to `false` on `resignFirstResponder`; ## 🤔 How Has This Been Tested? Tested manually on iPhone 16 (iOS 18.4). ## 📸 Screenshots (if appropriate): |Before|After| |-------|-----| |<video src="https://github.com/user-attachments/assets/acaf97f2-87d6-429a-b704-7d104abbba22">|<video src="https://github.com/user-attachments/assets/63e704aa-2b6f-4058-83ff-0cf6dcbca06c">| ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed
1 parent 6531fc9 commit 46bb921

1 file changed

Lines changed: 3 additions & 0 deletions

File tree

ios/swizzling/UIResponderSwizzle.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ extension UIResponder {
7272

7373
// Postpone execution of the original resignFirstResponder
7474
DispatchQueue.main.asyncAfter(deadline: .now() + UIUtils.nextFrame) {
75+
NotificationCenter.default.post(
76+
name: .shouldIgnoreKeyboardEvents, object: nil, userInfo: ["ignore": false]
77+
)
7578
(self as? TextInput)?.inputAccessoryView = nil
7679
KeyboardAreaExtender.shared.remove()
7780
_ = self.callOriginalResignFirstResponder(originalResignSelector)

0 commit comments

Comments
 (0)