iPhone12及以上设备react-native-pager-view的onPageScroll返回错误位置求助
解决react-native-pager-view在Modal中iPhone12+设备上position值异常问题
问题场景
使用react-native-pager-view@^6.1.2在react-native-modal内实现页面滑动时,仅iPhone12及以上设备出现异常:滑动切换页面时onPageScroll回调两次触发,第二次返回错误的position=0,导致当前页码状态被错误重置。
解决方案
方案1:改用onPageSelected更新页码状态
onPageScroll是滚动过程中的实时回调,会返回滚动过程中的中间position值,不适合直接用来更新当前选中页码。改用onPageSelected(仅在页面切换完成后触发一次)能精准获取最终选中的页码:
import PagerView, { PagerViewOnPageSelectedEvent } from 'react-native-pager-view'; import Modal from 'react-native-modal'; const onPageSelected = useCallback((e: PagerViewOnPageSelectedEvent) => { setCurrentTabIndex(e.nativeEvent.position); }, []); return ( <Modal isVisible={isVisible}> <SafeAreaView> <View> <PagerView ref={viewPager} initialPage={0} onPageSelected={onPageSelected} > {list.map((item) => ( <View key={item.id}> {item.content} </View> ))} </PagerView> </View> </SafeAreaView> </Modal> );
方案2:给PagerView设置明确高度
iPhone12+的屏幕布局特性可能导致Modal内的PagerView布局不稳定,引发原生层位置计算偏差。给PagerView或其父容器设置固定高度,稳定组件布局:
// 给PagerView父容器设置高度 <View style={{ height: '100%' }}> <PagerView ref={viewPager} initialPage={0} onPageScroll={onPageScroll} onPageSelected={onPageSelected} style={{ flex: 1 }} > {list.map((item) => ( <View key={item.id}> {item.content} </View> ))} </PagerView> </View>
方案3:延迟初始化PagerView
等待Modal完全渲染并完成动画后,再挂载PagerView,避免布局未稳定时初始化组件:
import { useState, useEffect, useCallback } from 'react'; import PagerView, { PagerViewOnPageScrollEvent, PagerViewOnPageSelectedEvent } from 'react-native-pager-view'; import Modal from 'react-native-modal'; const [modalReady, setModalReady] = useState(false); useEffect(() => { if (isVisible) { const timer = setTimeout(() => setModalReady(true), 100); return () => clearTimeout(timer); } else { setModalReady(false); } }, [isVisible]); return ( <Modal isVisible={isVisible}> <SafeAreaView> <View> {modalReady && ( <PagerView ref={viewPager} initialPage={0} onPageScroll={onPageScroll} onPageSelected={onPageSelected} > {list.map((item) => ( <View key={item.id}> {item.content} </View> ))} </PagerView> )} </View> </SafeAreaView> </Modal> );
内容的提问来源于stack exchange,提问作者raccoon
相关产品推荐
相关产品推荐

