React Native スクロール位置取得 (iOS)
React NativeでScrollViewの現在のスクロール位置を取得する (iOS編)
onScrollプロパティを利用する
- イベントハンドラ内で、
nativeEvent.contentOffset.x
とnativeEvent.contentOffset.y
を使って水平および垂直方向のスクロール位置を取得できます。 onScroll
プロパティは、ScrollViewがスクロールされたときにイベントハンドラを呼び出します。
import { ScrollView } from 'react-native';
function MyScrollView() {
const handleScroll = (event) => {
const x = event.nativeEvent.contentOffset.x;
const y = event.nativeEvent.contentOffset.y;
console.log(`Scroll position: x=${x}, y=${y}`);
};
return (
<ScrollView onScroll={handleScroll}>
{/* Your content here */}
</ScrollView>
);
}
useRefフックとmeasureLayoutメソッドを使う
useRef
フックでScrollViewの参照を取得し、measureLayout
メソッドを使ってレイアウト情報とスクロール位置を取得できます。
import { useRef, useEffect } from 'react';
import { ScrollView, findNodeHandle } from 'react-native';
function MyScrollView() {
const scrollViewRef = useRef(null);
useEffect(() => {
const nodeHandle = findNodeHandle(scrollViewRef.current);
if (nodeHandle) {
scrollViewRef.current.measureLayout((x, y, width, height) => {
const scrollX = scrollViewRef.current.contentOffset.x;
const scrollY = scrollViewRef.current.contentOffset.y;
console.log(`Scroll position: x=${scrollX}, y=${scrollY}`);
});
}
}, []);
return (
<ScrollView ref={scrollViewRef}>
{/* Your content here */}
</ScrollView>
);
}
注意
- iOSでは、
measureLayout
メソッドはメインスレッドで実行されるため、頻繁な呼び出しはパフォーマンスに影響を与える可能性があります。必要に応じて、requestAnimationFrame
を使って最適化してください。 onScroll
プロパティは、スクロールが停止したときにのみイベントをトリガーします。リアルタイムのスクロール位置が必要な場合は、useRef
フックとmeasureLayout
メソッドを使う方法が適しています。
import { ScrollView } from 'react-native';
function MyScrollView() {
const handleScroll = (event) => {
const x = event.nativeEvent.contentOffset.x;
const y = event.nativeEvent.contentOffset.y;
console.log(`Scroll position: x=${x}, y=${y}`);
};
return (
<ScrollView onScroll={handleScroll}>
{/* Your content here */}
</ScrollView>
);
}
import { useRef, useEffect } from 'react';
import { ScrollView, findNodeHandle } from 'react-native';
function MyScrollView() {
const scrollViewRef = useRef(null);
useEffect(() => {
const nodeHandle = findNodeHandle(scrollViewRef.current);
if (nodeHandle) {
scrollViewRef.current.measureLayout((x, y, width, height) => {
const scrollX = scrollViewRef.current.contentOffset.x;
const scrollY = scrollViewRef.current.contentOffset.y;
console.log(`Scroll position: x=${scrollX}, y=${scrollY}`);
});
}
}, []);
return (
<ScrollView ref={scrollViewRef}>
{/* Your content here */}
</ScrollView>
);
}
Animated APIを利用する
Animated.Value
を使ってスクロール位置を管理し、Animated.event
を使ってスクロールイベントを処理できます。Animated
APIは、アニメーションやインタラクションを管理するための強力なツールです。
import { Animated, ScrollView } from 'react-native';
function MyScrollView() {
const scrollY = new Animated.Value(0);
const handleScroll = Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
{ useNativeDriver: true }
);
return (
<Animated.ScrollView
onScroll={handleScroll}
scrollEventThrottle={16}
>
{/* Your content here */}
</Animated.ScrollView>
);
}
scrollEventThrottle
プロパティは、スクロールイベントの発生頻度を制限し、パフォーマンスを最適化します。Animated.event
のuseNativeDriver
プロパティをtrue
に設定することで、アニメーション処理をネイティブ側で行い、パフォーマンスを向上させることができます。
カスタムフックを使用する
- カスタムフックを作成して、スクロール位置の管理と取得をカプセル化できます。
import { useRef, useEffect, useState } from 'react';
import { ScrollView, findNodeHandle } from 'react-native';
function useScrollPosition(scrollViewRef) {
const [scrollPosition, setScrollPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const nodeHandle = findNodeHandle(scrollViewRef.current);
if (nodeHandle) {
scrollViewRef.current.measureLayout((x, y, width, height) => {
setScrollPosition({ x: scrollViewRef.current.contentOffset.x, y: scrollViewRef.current.contentOffset.y });
});
}
}, []);
return scrollPosition;
}
function MyScrollView() {
const scrollViewRef = useRef(null);
const scrollPosition = useScrollPosition(scrollViewRef);
return (
<ScrollView ref={scrollViewRef}>
{/* Your content here */}
<Text>Scroll position: x={scrollPosition.x}, y={scrollPosition.y}</Text>
</ScrollView>
);
}
ios reactjs react-native