React-native-navigation: Dismiss keyboard when pushing screen not working

Created on 11 Dec 2017  路  21Comments  路  Source: wix/react-native-navigation

I want to dismiss the keyboard when pushing a new screen to navigator, but nothing happens and when I go back the keyboard is still open.
The container of the screen where the keyboard is, is a scrollview with keyboardShouldPersistTaps='always'.
So what I'm trying to do is
Keyboard.dismiss()
this.props.navigator.push({ screen: 'colorPicker', title: 'Color Picker' })


Environment

  • React Native Navigation version: ^1.1.300
  • React Native version: 0.49.3
  • Platform(s) (iOS, Android, or both?): iOS
  • Device info (Simulator/Device? OS version? Debug/Release?): Simulator/Device. iOS version 11.0.3
馃彋 stale

Most helpful comment

I've also run into this issue, although when returning to the screen I'm unable to dismiss the keyboard at all. Definitely a bug here.

I'm also using a promise based workaround, though rather than an arbitrary time which may be too high or too low, no way of knowing, I'm waiting for the keyboardWillChangeFrame event which appears to be the first to occur when the keyboard dismisses. It doesn't seem to fire on Android though so I'm also using the keyboardDidHide event.

The promise will never resolve if the keyboard isn't open, so you'd need some way of tracking that to only use the method if needed.

````es6
new Promise((resolve, reject) => {
const frameListener = Keyboard.addListener('keyboardWillChangeFrame', () => {
frameListener.remove()
didListener.remove()
resolve()
})

const didListener = Keyboard.addListener('keyboardDidHide', () => {
frameListener.remove()
didListener.remove()
resolve()
})

Keyboard.dismiss()
})
````

All 21 comments

Maybe you have found the fix to this, however, for future people looking at the same issue as I have been, here is how I fixed it:

let dismissKeyBoard = () => { return new Promise((resolve, reject) => { Keyboard.dismiss(); setTimeout(() => { resolve(); }, 5); }); };

I've also run into this issue, although when returning to the screen I'm unable to dismiss the keyboard at all. Definitely a bug here.

I'm also using a promise based workaround, though rather than an arbitrary time which may be too high or too low, no way of knowing, I'm waiting for the keyboardWillChangeFrame event which appears to be the first to occur when the keyboard dismisses. It doesn't seem to fire on Android though so I'm also using the keyboardDidHide event.

The promise will never resolve if the keyboard isn't open, so you'd need some way of tracking that to only use the method if needed.

````es6
new Promise((resolve, reject) => {
const frameListener = Keyboard.addListener('keyboardWillChangeFrame', () => {
frameListener.remove()
didListener.remove()
resolve()
})

const didListener = Keyboard.addListener('keyboardDidHide', () => {
frameListener.remove()
didListener.remove()
resolve()
})

Keyboard.dismiss()
})
````

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you believe the issue is still relevant, please test on the latest version and report back. Thank you for your contributions.

The issue has been closed for inactivity.

I've actually couldn't dismiss the keyboard after go back from pushed screen.

Maybe this workaround can be helpful. Instead of using timeouts you can use InteractionManager.

Keybaord.dismiss();
InteractionManager.runAfterInteractions(() => {
  // screen push logic
})

It's a pity we are still having this issue with RNN 2.4.0... Can we reopen it and treat it like a bug?

The issue still occure in IOS. I trying dimiss keyboard before push new screen but not working.
RN: 0.59.3

+1

+1

+1, does anybody found any workaround? @huecnt-1493 @oferRounds @JerakRus

hi @chris-topher19
The only workaround I found for now is to push the new screen after the keyboard dismissed. That is:

Keyboard.dismiss()
InteractionManager.runAfterInteractions(() => {
    this.props.navigator.push(navProps)
})

After upgrading to [email protected], the InteractionManager.runAfterInteractions(() => {}) workaround does not work anymore. Anyone else running into the same issue after upgrading?

@chris-topher19
Did the InteractionManager.runAfterInteractions work for you?

I was able to work around this issue with a really hacky way after I tried numerous ways to resolve the keyboard issue.

It's not the best way but it's something that works for now and something I will continue to monitor.

After trying to debug this issue, I stumbled on a way for the Keyboard to dismiss on Android.

Basically, showing an overlay before a push component action dismisses the Keyboard.

InteractionManager.runAfterInteractions(async() => { await Navigation.showOverlay({...}) Navigation.push({...}) })

I dismiss the overlay component right away and style it with height: 0.

This workaround worked for me. Simply put the navigation push code inside a set timeout after a keyboard dismiss function call.

Keyboard.dismiss(); 

setTimeout(() => {
  // Navigation push code
}, 0);

@byonghun experiencing the same issue here with [email protected]

For me requestIdleCallback fixed the issue.

Keyboard.dismiss();
requestIdleCallback( () => {
          // push your screen here
} );

Thanks @hossamnasser938 it worked for me. However, I'd be curious to know why it works if you have some more details :)

still happening, none of the above works

@noway Can you please push a project with a reproduction?

Sorry, don't think I have bandwidth for that... But what I found out which I hope helps someone: don't use Keyboard.dismiss and instead use textInputRef.focus();textInputRef.blur(), yep call focus first and then blur to actually dismiss the keyboard.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SudoPlz picture SudoPlz  路  31Comments

mohdabbas picture mohdabbas  路  93Comments

yusufyildirim picture yusufyildirim  路  53Comments

fuatsengul picture fuatsengul  路  40Comments

diennguyentien picture diennguyentien  路  59Comments