Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS] OverKeyboardView does not work when the keyboard is not active #618

Closed
thespacemanatee opened this issue Oct 7, 2024 · 7 comments · Fixed by #621
Closed

[iOS] OverKeyboardView does not work when the keyboard is not active #618

thespacemanatee opened this issue Oct 7, 2024 · 7 comments · Fixed by #621
Assignees
Labels
🍎 iOS iOS specific OverKeyboardView Anything related to OverKeyboardView

Comments

@thespacemanatee
Copy link
Contributor

Describe the bug

When I use this component, it works as expected on Android, but on iOS, the children of OverKeyboardView are invisible when the keyboard is not active. I know they are rendered because they show up in the element inspector and can be interacted with (buttons are still pressable).

I think this happens because UIRemoteKeyboardWindow is not available when the keyboard is not active, but I don't think it is expected for the contents to be invisible in such cases. If you look at Telegram, the popover can be opened whether or not the keyboard is active.

Code snippet

<OverKeyboardView visible={popoverModalVisible}>
  <View
    className={cn('absolute inset-0', className)}
    accessibilityViewIsModal={popoverModalVisible}
    onAccessibilityEscape={onRequestClose}
    pointerEvents="box-none"
    style={style}>
    {popoverContent}
  </View>
</OverKeyboardView>

Repo for reproducing

Please let me know if you need a repro, but I believe it should be fairly easy to reproduce.

To Reproduce
Steps to reproduce the behavior:

I tried my best to run the example ios app but I'm getting this error:

Screenshot 2024-10-08 at 12 07 57 AM

Expected behavior

When the keyboard is active, the children in OverKeyboardView should not be invisible.

Screenshots

iOS

simulator_screenshot_ABDF4AEB-BC2F-4088-AB87-DD494B823B18

Android

Screenshot_1728317773

Smartphone (please complete the following information):

  • Device: iPad mini
  • OS: iOS 18.1
  • RN version: 0.75.3
  • RN architecture: Paper
  • JS engine: Hermes
  • Library version: 1.14.0
@kirillzyusko
Copy link
Owner

@thespacemanatee thank you for the issue!

Can you try to comment out a line in example/ios/Podfile with ccache_enabled, reinstall Pods and try again?

The thing is that in my example project everything works (i.e. view is shown even when the keyboard is not visible).
In case when the keyboard window is not available, then I am attaching a view to the last available window.

I am responding to you from a mobile device, so can't share any links, but if you can provide a reproduction example - it would help a lot.

In the example app I tested a scenario that you described and it was working well 🙈

@kirillzyusko kirillzyusko added 🍎 iOS iOS specific OverKeyboardView Anything related to OverKeyboardView labels Oct 7, 2024
@thespacemanatee
Copy link
Contributor Author

@kirillzyusko Thank you for the fast reply! I'll try to find some time this week to create a repro, but something that may be of help is that I am using the Native Stack Navigator from @react-navigation/[email protected] and [email protected]. I recall that this combination has caused problems with this library in the past so just thought that this might be useful to test!

@kirillzyusko
Copy link
Owner

I'm also using @react-navigation/[email protected] and [email protected] and just tested with native-stacks and it still works 🤷‍♂️ (the blue rectangle is in OverKeyboardView): https://github.com/kirillzyusko/react-native-keyboard-controller/blob/main/example/src/screens/Examples/OverKeyboardView/index.tsx


I think this happens because UIRemoteKeyboardWindow is not available when the keyboard is not active, but I don't think it is expected for the contents to be invisible in such cases.

I'm attaching to last window if keyboard window is not available:

return keyboardWindow ?? UIApplication.shared.windows.last

So yeah, really curious what is preventing this component from being working in your case 👀

@thespacemanatee
Copy link
Contributor Author

thespacemanatee commented Oct 8, 2024

@kirillzyusko Some good news, I found a more robust solution that works for me. I believe UIApplication.shared.window has been deprecated since iOS 15 (although I'm aware this is not the root cause of the problem), and the way forward is to use UIApplication.shared.connectedScenes. Could you verify if it works on your example project? If so, shall I open a PR? 😄

diff --git a/node_modules/react-native-keyboard-controller/ios/extensions/UIWindow.swift b/node_modules/react-native-keyboard-controller/ios/extensions/UIWindow.swift
index ead6e37..b4e1d4d 100644
--- a/node_modules/react-native-keyboard-controller/ios/extensions/UIWindow.swift
+++ b/node_modules/react-native-keyboard-controller/ios/extensions/UIWindow.swift
@@ -38,7 +38,22 @@ public extension UIWindow {
 
     func getTopWindow() -> UIWindow? {
       // Return the keyboard window if it's available, otherwise return the last window

@@ -12,9 +12,14 @@ index ead6e37..f61bd5b 100644
+      }
+      
+      if #available(iOS 13.0, *) {
+        for scene in UIApplication.shared.connectedScenes {
+          if scene.activationState == .foregroundActive,
+            let windowScene = scene as? UIWindowScene,
+            let keyWindow = windowScene.windows.first(where: { $0.isKeyWindow }) {
+            return keyWindow
+          }
+        }
+        return nil
+      } else {
+        return UIApplication.shared.windows.last { $0.isKeyWindow }
+      }

@kirillzyusko
Copy link
Owner

Thank you for investigation @thespacemanatee ! Appreciate that!

Yeah, your code work well in example project - I left one comment what would be better to change, but overall I'm happy to have these changes 😊

@thespacemanatee
Copy link
Contributor Author

@kirillzyusko I left a comment here for posterity. I also wanted to add that it seems OverKeyboardView is inspired by FullWindowOverlay from react-native-screens and I don't see the same conflicts with navigation and the overlay. I don't have the bandwidth to investigate further for now so I'm just noting this down for future work!

@kirillzyusko
Copy link
Owner

I also wanted to add that it seems OverKeyboardView is inspired by FullWindowOverlay from react-native-screens and I don't see the same conflicts with navigation and the overlay.

FullWindowOverlay was inspired by Modal implementation from react-native and I also used Modal implementation for a reference, so yeah, the implementation with FullWindowOverlay will be similar anyway 🙃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🍎 iOS iOS specific OverKeyboardView Anything related to OverKeyboardView
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants