2021. 11. 11. 22:39ㆍ공부내용 공유하기
RN의 SafeAreaView 컴포넌트는 최신 IOS 기기에서 발생하는 노치 영역 및 홈 버튼 영역(?)에 대한 영역 보장을 해주는 컴포넌트이다.
즉 달리 말하면 SafeAreaView 컴포넌트가 위치한 영역을 기준으로 노치영역과 홈 버튼 영역에 대한 보장이 이뤄진다고 할 수 있다.
따라서 IOS에서 상단이나 하단 영역에 대한 SafeArea 보장을 받기 원한다면 SafeAreaView를 사용해 원하는 영역을 Wrapping 하면 되는데, 다른 컴포넌트를 Wrapping 해서 사용하는 것 외에
export function Navigation() {
return (
<NavigationContainer>
<SafeAreaView
style={{
flex: 0,
backgroundColor: appTheme.appColor.colors.main,
zIndex: -10,
}}
/>
<StatusBar barStyle="dark-content" />
<App />
</NavigationContainer>
);
}
이런 식으로 사용해서 상단 노치영역만 확보하거나 하는 일이 가능하다.
이런 식의 스킬이 필요한 상황은 어떤 상황일까?
1. SafeArea 상/하단에 다른 스타일(배경색 등) 적용이 필요할 때
2. "keyboardWillShow" 이벤트로 받는 키보드 높이가 하단 노치 영역과 겹쳐서 문제가 생길 때
import { useEffect, useState } from "react";
import { Keyboard, Platform } from "react-native";
import { BOTTOM_SAFE_PADDING } from "@src/components/SafeContainer";
export default function useKeyboardEvent() {
const [isKeyboardActivate, setIsKeyboardActivate] = useState<boolean>(false);
const [keyboardHeight, setKeyboardHeight] = useState<number>(0);
useEffect(() => {
const keyboardWillShow = (e) => {
setIsKeyboardActivate(true);
if (Platform.OS === "ios") {
setKeyboardHeight(e.endCoordinates.height - BOTTOM_SAFE_PADDING);
}
};
const keyboardWillHide = () => {
setIsKeyboardActivate(false);
if (Platform.OS === "ios") {
setKeyboardHeight(0);
}
};
if (Platform.OS === "android") {
Keyboard.addListener("keyboardDidShow", keyboardWillShow);
Keyboard.addListener("keyboardDidHide", keyboardWillHide);
} else if (Platform.OS === "ios") {
Keyboard.addListener("keyboardWillShow", keyboardWillShow);
Keyboard.addListener("keyboardWillHide", keyboardWillHide);
}
return () => {
if (Platform.OS === "android") {
Keyboard.removeListener("keyboardDidShow", keyboardWillShow);
Keyboard.removeListener("keyboardDidHide", keyboardWillHide);
} else if (Platform.OS === "ios") {
Keyboard.removeListener("keyboardWillShow", keyboardWillShow);
Keyboard.removeListener("keyboardWillHide", keyboardWillHide);
}
};
}, []);
return { isKeyboardActivate, keyboardHeight };
}
평소에는 하단에 round 형태로 위치하다가 키보드 팝업 시에 round제거 후 하단에 붙는 버튼을 구현해야 한다면, IOS에서는 두 가지 방법이 있을 것이다.
1) 키보드 높이를 계산해서 버튼의 위치를 올려주거나
2) 키보드가 올라간 만큼 나머지 영역의 크기를 줄여 버튼이 자연스럽게 아래에 붙도록 하거나
지금 진행하는 프로젝트에서는 전자의 방식으로 구현중이었는데, 이벤트에 있는 endCoordinates를 통해 키보드 높이를 구할 수 있었다.
다만 그 높이가 실제 키보드의 높이와 상이했다.
키보드의 높이는 노치 영역부터 시작한 키보드의 진짜 높이였는데, 우리 앱에서의 bottom 기준점은 SafeAreaView로 인해 아래쪽 홈버튼 영역 위쪽으로 잡혀있었으니까..
이 문제를 해결하기 위해 아래쪽은 SafeAreaView를 두지 않았고, IOS의 경우 아래 패딩 영역을 추가해 주었다.(키보드 높이에서 해당 패딩 높이를 빼면 버튼 위치가 정확히 키보드 위로 향한다)
추후 IOS 버전을 통해 패딩값을 분기 처리하면, 별문제 없이 사용할 수 있을 것 같다.