diff --git a/src/views/KeyboardManager.tsx b/src/views/KeyboardManager.tsx index 01721bb4d..4e8dcfe27 100644 --- a/src/views/KeyboardManager.tsx +++ b/src/views/KeyboardManager.tsx @@ -13,6 +13,7 @@ export default class KeyboardManager extends React.Component { // Numeric id of the previously focused text input // When a gesture didn't change the tab, we can restore the focused input with this private previouslyFocusedTextInput: number | null = null; + private startTimestamp: number = 0; private handlePageChangeStart = () => { const input = TextInput.State.currentlyFocusedField(); @@ -22,6 +23,9 @@ export default class KeyboardManager extends React.Component { // Store the id of this input so we can refocus it if change was cancelled this.previouslyFocusedTextInput = input; + + // Store timestamp for touch start + this.startTimestamp = Date.now(); }; private handlePageChangeConfirm = () => { @@ -36,10 +40,23 @@ export default class KeyboardManager extends React.Component { const input = this.previouslyFocusedTextInput; if (input) { - TextInput.State.focusTextInput(input); - } + // If the interaction was super short we should make sure keyboard won't hide again. - this.previouslyFocusedTextInput = null; + // Too fast input refocus will result only in keyboard flashing on screen and hiding right away. + // During first ~100ms keyboard will be dismissed no matter what, + // so we have to make sure it won't interrupt input refocus logic. + // That's why when the interaction is shorter than 100ms we add delay so it won't hide once again. + // Subtracting timestamps makes us sure the delay is executed only when needed. + if (Date.now() - this.startTimestamp < 100) { + setTimeout(() => { + TextInput.State.focusTextInput(input); + this.previouslyFocusedTextInput = null; + }, 100); + } else { + TextInput.State.focusTextInput(input); + this.previouslyFocusedTextInput = null; + } + } }; render() {