React Native에서 다중 클릭 이벤트 처리
22208 단어 reactandroidreactnativeios
React Native의 클릭 이벤트 소개
React Native는 클릭 이벤트를 처리하기 위한 3가지 기본 기본 요소를 제공합니다.
이들 중 하나를 사용하는 것은 꽤 일반적인 일입니다. 클릭 이벤트에 응답해야 하는 구성 요소를 래핑하기만 하면 됩니다.
// imports...
<TouchableHighlight onPress={() => console.log('Clicked')}>
<Text>Click me</Text>
</TouchableHighlight>
터치 가능한 문제
대부분의 사용 사례에서 잘 작동하지만 처리할 수 없는 까다로운 상황이 있습니다. 단일 클릭, 더블 클릭 및 길게 누르기 이벤트를 모두 동일한 요소에서 처리하는 경우를 고려하십시오.
구조에 PanResponder
PanResponder는 하위 수준Gesture Responder System API에 예측 가능한 래퍼를 제공합니다. 터치 이벤트에 대한 훨씬 세분화된 제어를 제공하고 터치 시작 위치, 터치 종료 위치, 제스처 속도 등과 같은 유용한 메타 정보에 대한 액세스도 제공합니다.
PanResponder를 사용하여
View
컴포넌트가 터치 이벤트에 응답하도록 하는 방법을 알아보겠습니다.import { View, PanResponder, Text } from 'react-native';
const MyComponent = () => {
const responder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onMoveShouldSetPanResponder: () => true,
onPanResponderStart: (event) => {
console.log('Touch has started !');
},
onPanResponderRelease: (event, gestureState) => {
console.log('Touch has ended !');
},
onPanResponderTerminate: () => {},
});
return (
<View {...responder.panHandlers}>
<Text>Click Me </Text>
</View>
);
};
onStartShouldSetPanResponder
는 true
를 반환해야 터치 이벤트 시작 시 뷰가 응답자가 될 수 있습니다.onMoveShouldSetPanResponder
는 true
를 반환해야 드래그 이벤트가 시작될 때 뷰가 응답자가 될 수 있습니다.onPanResponderStart
콜백은 PanResponder
가 터치 이벤트를 등록할 때 시작됩니다.onPanResponderRelease
터치가 해제되면 콜백이 시작됩니다.onPanResponderTerminate
보기에서 응답자를 가져오면 콜백이 시작됩니다. 이것은 다른 보기가 onPanResponderTerminationRequest
를 호출하거나묻지 않는 OS(iOS의 제어 센터/알림 센터에서 발생).
더블 클릭이 작동하도록 하려면 카운터를 사용하고 클릭 사이의 최대 시간을 설정하여 더블 클릭으로 처리해야 합니다. 클릭 사이의 400ms 지연은 시작하기에 좋은 위치입니다.
handleTap
를 사용하여 타이머를 기반으로 클릭 이벤트 유형을 결정합니다.const MyComponent = () => {
const [isTerminated, setTerminated] = useState(false);
const [touchStartTime, setTouchStartTime] = useState(0);
const [lastTap, setLastTap] = useState(0);
const DOUBLE_PRESS_DELAY = 400;
const handleTap = (event, gestureState) => {
const timeNow = Date.now();
if (lastTap && timeNow - lastTap < DOUBLE_PRESS_DELAY) {
console.log('Handle double press');
} else {
setLastTap(timeNow);
const timeout = setTimeout(() => {
setLastTap(0);
console.log('Handle single press');
}, DOUBLE_PRESS_DELAY);
}
};
const responder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onMoveShouldSetPanResponder: () => true,
onPanResponderStart: () => {
const timeout = setTimeout(() => {
if (!isTerminated) {
setTouchStartTime(Date.now());
}
});
},
onPanResponderRelease: (event, gestureState) => {
handleTap(event, gestureState);
},
onPanResponderTerminate: () => {
setTerminated(true);
},
});
return (
<View {...responder.panHandlers}>
<Text>Click Me </Text>
</View>
);
};
이제 길게 누르기가 작동하도록 하려면 700ms 지연이 있는 다른 카운터가 필요합니다. 한 번 누르는지 두 번 누르는지 확인하기 전에 길게 누르는지 먼저 확인합니다.
handlePressOut
를 사용하여 클릭 유형을 결정하고 이에 대한 작업을 위임합니다.const MyComponent = () => {
const [isTerminated, setTerminated] = useState(false);
const [touchStartTime, setTouchStartTime] = useState(0);
const [lastTap, setLastTap] = useState(0);
const [longPressTimer, setLongPressTimer] = useState(0);
const [singlePressTimer, setSinglePressTimer] = useState(0);
const DOUBLE_PRESS_DELAY = 400;
const LONG_PRESS_DELAY = 700;
const cancelLongPressTimer = () => {
if (longPressTimer) {
clearTimeout(longPressTimer);
setLongPressTimer(0);
}
};
const cancelSinglePressTimer = () => {
if (singlePressTimer) {
clearTimeout(singlePressTimer);
setSinglePressTimer(0);
}
};
const handleTap = (event, gestureState) => {
cancelSinglePressTimer();
const timeNow = Date.now();
if (lastTap && timeNow - lastTap < DOUBLE_PRESS_DELAY) {
console.log('Handle double press');
} else {
setLastTap(timeNow);
const timeout = setTimeout(() => {
setLastTap(0);
console.log('Handle single press');
}, DOUBLE_PRESS_DELAY);
setSinglePressTimer(timeout);
}
};
const handlePressOut = (event, gestureState) => {
const elapsedTime = Date.now() - touchStartTime;
if (elapsedTime > LONG_PRESS_DELAY) {
console.log('Handle long press');
} else {
handleTap(event, gestureState); // handles the single or double click
}
setTouchStartTime(0);
};
const responder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onMoveShouldSetPanResponder: () => true,
onPanResponderStart: () => {
cancelLongPressTimer();
const timeout = setTimeout(() => {
if (!isTerminated) {
setTouchStartTime(Date.now());
}
});
setLongPressTimer(timeout);
},
onPanResponderRelease: (event, gestureState) => {
handlePressOut(event, gestureState);
},
onPanResponderTerminate: () => {
setTerminated(true);
},
});
return (
<View {...responder.panHandlers}>
<Text>Click Me </Text>
</View>
);
};
결론
동일한 요소에 대한 여러 클릭을 손쉽게 처리할 수 있도록 정확히 이 작업을 수행하는 react-native-gifted-touch을 만들었습니다. 라이브러리의 기본 시간 지연은 요구 사항에 더 잘 맞도록
props
를 사용하여 구성할 수 있습니다. 확인하시기 바랍니다.
Reference
이 문제에 관하여(React Native에서 다중 클릭 이벤트 처리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/joelraju/handling-multiple-click-events-in-react-native-292p텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)