리액트 네비게이션 (stack) 사용 중에 IOS 의 경우
좌측 스와이프해서 back stack 으로 이동이 가능합니다.
map view 등을 사용할 경우에는 이 동작을 막지 않으면,
지도 이동중에 back key 처럼 동작되어 불편함이 발생하므로
이부분 해결하고 넘어가야겠습니다.
- Swipe Back Disable
해결 방법은 gestureEnabled 한줄이면 됩니다.
단, 주로 안드로이드에서 쓰이는 gesture back 이나 back key를 제어하진 않습니다
gestureEnabled: false,
아래 doc 설명 처럼, Defaults to true on iOS, false on Android 입니다.
reactnavigation.org/docs/stack-navigator/#gestureenabled
아래 코드에서 BottomTabScreen (MapView가 있는) 에만 적용.
const Stack = createStackNavigator();
export default class MainScreen extends Component {
state = {
finishIntro: false,
}
async componentDidMount() {
setTimeout(() => {
SplashScreen.hide();
}, 1000);
try {
AsyncStorage.getItem("finishIntro").then((value) => {
if (value === "true") {
this.setState({finishIntro: true});
}
});
} catch (err) {
console.log("udonPeople error: " + err)
}
}
onRenderItem = ({ item }) => {
return (
<View style={globalStyles.IntroSlideContainer}>
<Image style={globalStyles.IntroSlideImageContainer} source={item.image} />
</View>
);
}
onDone = () => {
this.setState({finishIntro:true});
setAsyncStorage("finishIntro", "true");
}
render() {
if (this.state.finishIntro) {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Auth" component={AuthScreen}
options={() => ({
headerShown:false,
headerTitle:"로그인",
})}
/>
<Stack.Screen name="Home" component={BottomTabScreen}
options={() => ({
// headerLeft:() => <Header left={true} navigation={navigation}/>,
// headerRight:() => <Header left={false} navigation={navigation}/>,
// headerLeft:null,
// headerTitleAlign:"center",
headerShown:false,
headerTitle:"지도보기",
gestureEnabled: false,
})}
/>
<Stack.Screen name="LocationSetting" component={RegionScreen}
options={() => ({
headerTitleAlign:"center",
headerTitle:"지역 설정",
})}
/>
<Stack.Screen name="Setting" component={SettingScreen}
options={() => ({
headerTitleAlign:"center",
headerTitle:"설정",
})}
/>
<Stack.Screen name="WebCafe" component={WebCafeScreen}
options={() => ({
headerTitleAlign:"center",
headerTitle:"카페 방문",
})}
/>
<Stack.Screen name="AppManual" component={ManualScreen}
options={() => ({
headerTitleAlign:"center",
headerTitle:"공지사항",
})}
/>
</Stack.Navigator>
</NavigationContainer>
);
} else {
return <AppIntroSlider renderItem={this.onRenderItem} data={introSlide} onDone={this.onDone}/>;
}
}
}
왼쪽 - 수정 후 mapview 에서 더이상 swipe back 불가(settingscreen은 가능)
오른쪽- 적용 전(mapview swipe back 가능)
- gesture back, edge back, back key disable
android back key event 를 control 하는 코드는 다음과 같습니다.
그리고, back key 2회시 (3초안에) app 종료하는 코드도 함께 추가 했습니다.
onBackPressed 에서 return true 시 back 을 block 시켜버립니다.
import {BackHandler, ToastAndroid } from "react-native";
state = {
validCloseWindow: false,
};
componentDidMount() {
if (Platform.OS === 'android') {
BackHandler.addEventListener('hardwareBackPress', this.onBackPressed);
}
}
onBackPressed = () => {
const duration = 3 * 1000;
if (this.state.validCloseWindow) {
BackHandler.exitApp();
}
this.setState({validCloseWindow: true});
setTimeout(() => {
this.setState({validCloseWindow: false});
}, duration);
ToastAndroid.show("버튼을 한번 더 누르면 종료됩니다", duration);
return true;
}
componentWillUnmount() {
if (Platform.OS === 'android') {
BackHandler.removeEventListener('hardwareBackPress', this.onBackPressed);
}
}
그리고, Preventing going back 코드는
swipe back 뿐만 아니라, back 관련된 걸 다 막아버립니다.
class component 는 componentDidMount() 에, function component 는 useEffect() 에 밀어넣으면 됩니다.
실제 써보니, 잘 되던 다른 동작까지 막아 버려서
좀더 파보고 써야겠습니다.
A stack 에 아래 코드를 넣으면,
A -> B -> C-> A stack navigate 이동 시 A로 못돌아오네요.
componentDidMount() {
this.props.navigation.addListener('beforeRemove', (e) => {
e.preventDefault();
console.log(" beforeRemove " + e);
});
}
reactnavigation.org/docs/preventing-going-back
'Mobile 개발 > RN(React Native)' 카테고리의 다른 글
RN - 자주 사용되는 javascript 문자열 처리 (0) | 2020.12.27 |
---|---|
RN TroubleShooting: Expiring Daemon because JVM heap space is exhausted (0) | 2020.12.27 |
RN - SplashScreen 적용, 그리고 ios xcode bug (0) | 2020.12.23 |
RN - Apple Social Login with Firebase (0) | 2020.12.19 |
RN TroubleShooting: firebase 이용한 Android app 구글 로그인 안됨 (3) | 2020.12.19 |