xamous/react-native-smooth-pincode-input

autoFocus is not running perfectly (most of the time)

qasimgit opened this issue · 6 comments

setting autofocus true does'nt make it smooth when component did mount, also tried ref method but still does'nt working

I'm having same issue.

jffr commented

For me it is working on iOS (Simulator), but not on Android:

const PincodeInput = ({
  value,
  setValue,
  inputRef,
  onFulfill
}) => (
  <SmoothPincodeInput
    password
    mask="*"
    ref={inputRef}
    containerStyle={styles.wrapper}
    cellStyle={styles.cell}
    cellStyleFocused={styles.cellFocused}
    textStyle={styles.cellText}
    value={value}
    onTextChange={setValue}
    onFulfill={onFulfill}
    restrictToNumbers={true}
    animationFocused={null}
    autoFocus={true}
  />
)

Same here, autoFocus works on iOS but not on Android.

My workaround was to delay rendering SmoothPincodeInput a few ms after mounting my component.

jffr commented

Thanks @MatiasArriola, I noticed that I had to delay rendering for a second in order to see the keyboard. This was my solution:

const PincodeInput = ({
  value,
  setValue,
  inputRef,
  onFulfill
}) => {
  useEffect(() => {
    setTimeout(() => {
      // Fix auto focus for Android
      inputRef.current.focus()
    }, 1000)
  }, [inputRef])

  return (
    <SmoothPincodeInput
      password
      mask="*"
      ref={inputRef}
      containerStyle={styles.wrapper}
      cellStyle={styles.cell}
      cellStyleFocused={styles.cellFocused}
      textStyle={styles.cellText}
      value={value}
      onTextChange={setValue}
      onFulfill={onFulfill}
      restrictToNumbers={true}
      animationFocused={null}
      autoFocus={true}
    />
  )
}

Remove the autoFocus attribute if not you will have some issues.

const PincodeInput = ({
  value,
  setValue,
  inputRef,
  onFulfill
}) => {
  useEffect(() => {
    setTimeout(() => {
      // Fix auto focus for Android
      inputRef.current.focus()
    }, 1000)
  }, [inputRef])

  return (
    <SmoothPincodeInput
      password
      mask="*"
      ref={inputRef}
      containerStyle={styles.wrapper}
      cellStyle={styles.cell}
      cellStyleFocused={styles.cellFocused}
      textStyle={styles.cellText}
      value={value}
      onTextChange={setValue}
      onFulfill={onFulfill}
      restrictToNumbers={true}
      animationFocused={null}
    />
  )
}

if you have modal in prev screen, don't close the modal just move to your otp screen, and this my PIN screen, for your reference

  const pinInputRef = useRef(null);

  useFocusEffect(
    React.useCallback(() => {
      // Focus on the PIN input field when the page is focused
      setTimeout(() => {
        pinInputRef.current && pinInputRef.current?.focus();
      }, 500);

      // Cleanup function (optional)
      return () => {
        // Additional cleanup, if needed
      };
    }, [])
  );

 <SmoothPinCodeInput
            ref={pinInputRef}
            autoFocus={true}
            testID='PINInputText'
            accessibilityLabel="PINInputText"
            // editable={loading ? false : true}
            placeholder={
              <View
                style={{
                  width: 20,
                  height: 20,
                  borderRadius: 25,
                  borderColor: code_color.whiteCheese,
                  borderWidth: 1
                }}
              />
            }
            mask={
              <View
                style={{
                  width: 20,
                  height: 20,
                  borderRadius: 25,
                  backgroundColor: '#FFFFFF',
                }}
              />
            }
            maskDelay={0}
            password={true}
            cellStyle={null}
            cellStyleFocused={null}
            value={otp}
            codeLength={6}
            onTextChange={(val: any) => {
              setOtp(val)
            }}
            onFulfill={handleOTP}
          />