3

Description

I have a page in my app with two TextInput inside views covering the whole screen.

The two TextInput have a ref ref={refTextInput1}, ref={refTextInput2}. They also have a onSubmitEditing onSubmitEditing={() => refTextInput2()}, onSubmitEditing={() => refTextInput1()}.

So, when I press "return" on the keyboard, the focus will switch to the desired input but it's also making the whole screen jump/glitch which is really annoying and not wanted.

The focus should switch to the desired input without making the whole screen jump/glitch.

I searched everywhere on StackOverflow and Github Issues but didn't find a lot of issues with this particular problem. At first, I thought I had a problem similar to #30207, but after a while trying to find the problem, I think I found it.

The problem only occurs(I think) when Autofill Passwords is enabled in Settings>Passwords>Autofill Passwords. If I disable Autofill Passwords, the jump/glitch does not occurs.

I also noticed that the keyboard event is always triggered twice on focus with Autofill Passwords enabled, and only once on focus with Autofill Passwords disabled. It may also be related. (See the console when running the snack example.)

I looked at other apps, and they all seems fine in the same type of login screen. Instagram for example doesn't have this problem.

It might also be the way I made my screen, if there's a better way to do the same or similar screen, I would be open to suggestions.

React Native version:

System:
    OS: macOS 11.4
    CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
    Memory: 137.61 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.17.0 - /usr/local/bin/node
    Yarn: Not Found
    npm: 6.14.13 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.1 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4
    Android SDK:
      API Levels: 22, 23, 24, 25, 26, 27, 28, 29, 30
      Build Tools: 28.0.3, 29.0.2, 30.0.2
      System Images: android-30 | Google APIs Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.1 AI-201.8743.12.41.6953283
    Xcode: 12.5/12E262 - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_271 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.1 => 17.0.1 
    react-native: 0.64.1 => 0.64.1 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

  1. Make sure Autofill Passwords is enabled in Settings>Passwords>Autofill Passwords.
  2. Have at least two TextInput with a view taking the whole screen space.
  3. Focus on the next TextInput using "return" on the keyboard.

I also noticed that the keyboard event is always triggered twice on focus with Autofill Passwords enabled, and only once on focus with Autofill Passwords disabled. It may also be related. (See the console when running the snack example.)

Expected Results

When pressing "return" on the keyboard, the focus should switch to the desired input without making the whole screen jump/glitch. Like when Autofill Passwords is disabled in Settings>Passwords>Autofill Passwords.

Snack, code example, screenshot, or link to a repository:

Snack 1 is a simpler version of my issue. Snack 1: simple-keyboard-autofill-issue

Snack 2 is closer to what I really have in my app. Snack 2: my-app-keyboard-autofill-issue

Minimal code example: (from simple-keyboard-autofill-issue)

import React, { useState, useRef, useEffect } from 'react';
import { Text, View, KeyboardAvoidingView, TouchableWithoutFeedback, Keyboard, Platform, TextInput } from 'react-native';

export default function App() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');

  const refUsernameInput = useRef(null);
  const refPasswordInput = useRef(null);

  useEffect(() => {
    Keyboard.addListener('keyboardWillShow', keyboardWillShow);
    Keyboard.addListener('keyboardWillHide', keyboardWillHide);
s
    // cleanup function
    return () => {
      Keyboard.removeListener('keyboardWillShow', keyboardWillShow);
      Keyboard.removeListener('keyboardWillHide', keyboardWillHide);
    };
  }, []);

  const keyboardWillShow = () => {
    console.log('keyboardWillShow');
  };

  const keyboardWillHide = () => {
    console.log('keyboardWillHide');
  };

  return (
    <KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={{ flex: 1 }}>
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View style={{ flex: 1, justifyContent: 'space-around', paddingHorizontal: 20 }}>
            <TextInput
              blurOnSubmit={false}
              keyboardType="email-address"
              placeholder="Username or email"
              textContentType="username" // iOS
              onSubmitEditing={() => refPasswordInput.current.focus()}
              onChangeText={setUsername}
              value={username}
              ref={refUsernameInput}
              style={{
                borderColor: '#000',
                borderWidth: 0.5,
                height: 45,
                paddingHorizontal: 20,
                marginBottom: 5,
              }}
            />
            <TextInput
              blurOnSubmit={false}
              keyboardType="default"
              placeholder="Password"
              secureTextEntry
              textContentType="password" // iOS
              onSubmitEditing={() => refUsernameInput.current.focus()}
              onChangeText={setPassword}
              value={password}
              ref={refPasswordInput}
              style={{
                borderColor: '#000',
                borderWidth: 0.5,
                height: 45,
                paddingHorizontal: 20,
              }}
            />
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  );
}

Here you can see the screen recording taken from an iPhone 11 Pro with iOS 14.6: (Note that secureTextEntry was temporarily disabled while screen recording, the problem is still present)

https://user-images.githubusercontent.com/64789082/121977389-e7363080-cd53-11eb-9a4c-e26fc364bd03.MP4

Samuel Beaulieu
  • 143
  • 2
  • 7
  • this answer could be probable solution to your problem, https://stackoverflow.com/a/60733647/3237884 – nazmul Jun 15 '21 at 02:27
  • @nazmul yes it does fix the problem. Actually, removing `secureTextEntry` and `textContentType` also did the same trick, but either way I am now unable to autofill the TextInputs, which for a login screen is not acceptable. – Samuel Beaulieu Jun 16 '21 at 00:04

0 Answers0