ios homescreen layout shift fix

This commit is contained in:
tapframe 2025-10-19 12:49:10 +05:30
parent d5edec025c
commit 9ab99a1225
4 changed files with 26 additions and 22 deletions

View file

@ -77,10 +77,9 @@ const CatalogSection = ({ catalog }: CatalogSectionProps) => {
const keyExtractor = useCallback((item: StreamingContent) => `${item.id}-${item.type}`, []);
return (
<Animated.View
style={styles.catalogContainer}
<Animated.View
style={styles.catalogContainer}
entering={FadeIn.duration(400)}
layout={Layout.springify().damping(15).stiffness(150)}
>
<View style={styles.catalogHeader}>
<View style={styles.titleContainer}>

View file

@ -726,10 +726,9 @@ const ContinueWatchingSection = React.forwardRef<ContinueWatchingRef>((props, re
}
return (
<Animated.View
style={styles.container}
<Animated.View
style={styles.container}
entering={FadeIn.duration(350)}
layout={Layout.springify().damping(15).stiffness(150)}
>
<View style={styles.header}>
<View style={styles.titleContainer}>

View file

@ -185,10 +185,9 @@ export const ThisWeekSection = React.memo(() => {
};
return (
<Animated.View
style={styles.container}
<Animated.View
style={styles.container}
entering={FadeIn.duration(350)}
layout={Layout.springify().damping(15).stiffness(150)}
>
<View style={styles.header}>
<View style={styles.titleContainer}>

View file

@ -124,6 +124,16 @@ const HomeScreen = () => {
const totalCatalogsRef = useRef(0);
const [visibleCatalogCount, setVisibleCatalogCount] = useState(5); // Reduced for memory
const insets = useSafeAreaInsets();
// Stabilize insets to prevent iOS layout shifts
const [stableInsetsTop, setStableInsetsTop] = useState(insets.top);
useEffect(() => {
// Only update insets after initial mount to prevent shifting
const timer = setTimeout(() => {
setStableInsetsTop(insets.top);
}, 100);
return () => clearTimeout(timer);
}, [insets.top]);
const {
featuredContent,
@ -653,15 +663,11 @@ const HomeScreen = () => {
const renderListItem = useCallback(({ item }: { item: HomeScreenListItem; index: number }) => {
switch (item.type) {
case 'thisWeek':
return <Animated.View layout={Layout.springify().damping(15).stiffness(150)}>{memoizedThisWeekSection}</Animated.View>;
return memoizedThisWeekSection;
case 'continueWatching':
return null; // Moved to ListHeaderComponent to avoid remounts on scroll
case 'catalog':
return (
<Animated.View layout={Layout.springify().damping(15).stiffness(150)}>
<CatalogSection catalog={item.catalog} />
</Animated.View>
);
return <CatalogSection catalog={item.catalog} />;
case 'placeholder':
return (
<Animated.View>
@ -701,7 +707,7 @@ const HomeScreen = () => {
</Animated.View>
);
case 'welcome':
return <Animated.View layout={Layout.springify().damping(15).stiffness(150)}><FirstTimeWelcome /></Animated.View>;
return <FirstTimeWelcome />;
default:
return null;
}
@ -747,10 +753,10 @@ const HomeScreen = () => {
}
}, [toggleHeader]);
// Memoize content container style
const contentContainerStyle = useMemo(() =>
StyleSheet.flatten([styles.scrollContent, { paddingTop: insets.top }]),
[insets.top]
// Memoize content container style - use stable insets to prevent iOS shifting
const contentContainerStyle = useMemo(() =>
StyleSheet.flatten([styles.scrollContent, { paddingTop: stableInsetsTop }]),
[stableInsetsTop]
);
// Memoize the main content section
@ -775,7 +781,7 @@ const HomeScreen = () => {
onEndReached={handleLoadMoreCatalogs}
onEndReachedThreshold={0.6}
recycleItems={true}
maintainVisibleContentPosition
maintainVisibleContentPosition={Platform.OS !== 'ios'} // Disable on iOS to prevent shifting
onScroll={handleScroll}
/>
{/* Toasts are rendered globally at root */}
@ -1341,4 +1347,5 @@ const HomeScreenWithFocusSync = (props: any) => {
return <HomeScreen {...props} />;
};
export default React.memo(HomeScreenWithFocusSync);
export default React.memo(HomeScreenWithFocusSync);