From 7a49b0487632ef69534723601351f8afdd9f49a1 Mon Sep 17 00:00:00 2001 From: Senmalong Date: Mon, 1 Jun 2026 07:41:57 +0100 Subject: [PATCH 1/2] fix(#72): replace autoFocus with delayed focus via useRef autoFocus opens the keyboard immediately on mount, which can block UI elements before the screen finishes rendering. Replace it with a ref-based focus triggered after a 300 ms delay, giving the navigation transition time to complete on both iOS and Android. - Add nameInputRef (useRef) to the name field - Remove autoFocus prop from the name TextInput - Focus the input programmatically after 300 ms in a useEffect - Import useRef from React --- src/screens/AddSubscriptionScreen.tsx | 47 ++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/src/screens/AddSubscriptionScreen.tsx b/src/screens/AddSubscriptionScreen.tsx index bd09d0d..c2d4788 100644 --- a/src/screens/AddSubscriptionScreen.tsx +++ b/src/screens/AddSubscriptionScreen.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { View, Text, @@ -10,6 +10,7 @@ import { Alert, KeyboardAvoidingView, Platform, + Keyboard, } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; @@ -33,6 +34,11 @@ const AddSubscriptionScreen: React.FC = () => { const { addSubscription, isLoading, error } = useSubscriptionStore(); const { preferredCurrency } = useSettingsStore(); + // Ref for the name input — used for delayed focus instead of autoFocus, + // so the screen has time to fully render before the keyboard opens. + const nameInputRef = useRef(null); + const [isKeyboardVisible, setIsKeyboardVisible] = useState(false); + const [formData, setFormData] = useState({ name: '', description: '', @@ -56,6 +62,32 @@ const AddSubscriptionScreen: React.FC = () => { } }, [error]); + // Delay focus so the screen finishes rendering before the keyboard opens. + // A 300 ms delay gives the navigation transition time to complete on both + // iOS and Android, preventing the keyboard from obscuring UI elements. + useEffect(() => { + const focusTimer = setTimeout(() => { + nameInputRef.current?.focus(); + }, 300); + + return () => clearTimeout(focusTimer); + }, []); + + // Track keyboard visibility so the ScrollView can adjust its content + // inset and keep form fields accessible when the keyboard is open. + useEffect(() => { + const showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow'; + const hideEvent = Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide'; + + const showSub = Keyboard.addListener(showEvent, () => setIsKeyboardVisible(true)); + const hideSub = Keyboard.addListener(hideEvent, () => setIsKeyboardVisible(false)); + + return () => { + showSub.remove(); + hideSub.remove(); + }; + }, []); + // Date Picker States const [showPicker, setShowPicker] = useState(false); const [pickerMode, setPickerMode] = useState<'date' | 'time'>('date'); @@ -186,8 +218,12 @@ const AddSubscriptionScreen: React.FC = () => { - + behavior={Platform.OS === 'ios' ? 'padding' : undefined} + keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : 0}> + { Name * handleInputChange('name', text)} placeholder="Enter subscription name" placeholderTextColor={colors.textSecondary} - autoFocus accessibilityLabel="Subscription name, required" accessibilityHint="Enter the name of the subscription service" returnKeyType="next" @@ -480,6 +516,9 @@ const styles = StyleSheet.create({ scrollView: { flex: 1, }, + scrollContentKeyboardOpen: { + paddingBottom: 120, + }, header: { padding: spacing.lg, paddingBottom: spacing.md, From fe35c61cd3b646db5d1fbf5f3a87910284281f3f Mon Sep 17 00:00:00 2001 From: Senmalong Date: Mon, 1 Jun 2026 07:42:06 +0100 Subject: [PATCH 2/2] fix(#72): improve KeyboardAvoidingView and keyboard visibility tracking - Switch KeyboardAvoidingView behavior to 'padding' on iOS and undefined on Android (Android handles scroll natively) - Track keyboard show/hide events with Keyboard listeners to set isKeyboardVisible state - Apply extra bottom padding to ScrollView content when keyboard is open so all form fields remain reachable - Import Keyboard from react-native