문제 상황
리액트 네이티브에서
ScrollView내부에WebView로 지도를 넣었을 때, 사용자 인터랙션 중에 지도 화면이 제대로 움직이지 않고ScrollView와 충돌하는 현상이 발생할 수 있습니다. 특히 줌인/줌아웃과 같은 동작을 할 때ScrollView와 충돌하여 화면이 흔들리는 문제가 발생할 수 있습니다. 이 문제는 터치 이벤트가WebView에서ScrollView로 전달되어 발생하는데, 이를 해결하기 위해서는 두 영역의 스크롤 제어를 적절히 분리해야 합니다.
문제 원인
ScrollView와WebView의 터치 이벤트 충돌: 지도에서 발생하는 터치 이벤트(줌인/줌아웃)가ScrollView로 전달되어ScrollView가 움직이게 됩니다. 이로 인해WebView내의 지도를 원활하게 조작할 수 없게 됩니다.스크롤뷰와 지도간 터치 이벤트 충돌: 기본적으로
ScrollView는 터치가 발생하면 스크롤 이벤트를 처리하려 하기 때문에, 지도에서 발생하는 터치 이벤트가 스크롤뷰의 스크롤 이벤트로 처리되는 것이 문제입니다.
해결 방법
이 문제를 해결하기 위해서는 지도 영역에서 터치가 발생하면
ScrollView의 스크롤을 비활성화하고, 터치가 끝난 후에는 다시 스크롤을 활성화하는 방식으로 제어할 수 있습니다.이를 위해
useState훅을 사용하여 스크롤 상태를 관리하고,WebView의onTouchStart와onTouchEnd이벤트를 사용하여 스크롤 상태를 동적으로 제어합니다.
해결 방법 코드
import React, {useState} from 'react';
import {ScrollView, StyleSheet, View} from 'react-native';
import WebView from 'react-native-webview';
const MapComponent = () => {
const [scrollEnabled, setScrollEnabled] = useState(true); // 스크롤 제어 상태
return (
<ScrollView
scrollEnabled={scrollEnabled} // 스크롤 제어
showsVerticalScrollIndicator={false}>
<View style={styles.mapContainer}>
<WebView
originWhitelist={['*']}
source={{ uri: 'https://www.example.com/map' }} // 지도 URL 예시
scrollEnabled={false} // WebView 자체 스크롤 비활성화
onTouchStart={() => setScrollEnabled(false)} // 지도 터치 시 ScrollView 비활성화
onTouchEnd={() => setScrollEnabled(true)} // 터치 종료 시 ScrollView 활성화
/>
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
mapContainer: {
height: 400, // WebView의 높이 설정
},
});
export default MapComponent;
코드 설명
scrollEnabled상태:useState를 사용해ScrollView의 스크롤 활성화 여부를 관리합니다.scrollEnabled가true일 때는 스크롤이 가능하고,false일 때는 스크롤이 비활성화됩니다.onTouchStart와 onTouchEnd 이벤트:
onTouchStart:WebView(지도)가 터치될 때setScrollEnabled(false)를 호출하여ScrollView의 스크롤을 비활성화합니다. 이로 인해 지도를 줌인/줌아웃할 때ScrollView가 스크롤되지 않도록 방지할 수 있습니다.onTouchEnd: 터치가 끝났을 때 다시setScrollEnabled(true)를 호출하여 ScrollView의 스크롤을 활성화합니다.scrollEnabled={false}:
WebView자체의 스크롤은 비활성화되며, 사용자는 WebView 내부에서 터치 동작을 수행할 수 있습니다.