xamous / react-native-smooth-pincode-input

A cross-platform, smooth, lightweight, customizable PIN code input component for React Native.
MIT License
406 stars 139 forks source link

autoFocus is not running perfectly (most of the time) #72

Open qasimgit opened 3 years ago

qasimgit commented 3 years ago

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

stuart201 commented 3 years ago

I'm having same issue.

jffr commented 3 years ago

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}
  />
)
MatiasArriola commented 3 years ago

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 3 years ago

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}
    />
  )
}
joartola commented 2 years ago

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}
    />
  )
}
Febriansyah11 commented 9 months ago

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}
          />