# 외부 라이브러리를 활용한 동적 스타일링
달력 레이아웃
초기상황 : 아래와 같은 구조로 최상위에 calenderPage가 있고 그안에 calender에서 DateCell을 이중배열 map 돌려서 달력을 구현하고 있음.

# 문제상황 1
목표: 상단 Header와 바텀 Navigation을 제외한 가운데 빈 공간에 DateCell로 만든 표가 헤더와 네비게이션을 제외한 영역에 알맞게 꽉차길 원함. 기기에 맞게 동적으로 스타일링 하기 위해 useWindowDimensions()를 이용해 높이를 계산하고, Header와 Navigation의 높이를 뺀 후 나누기 6하는 방법을 사용하였지만 작동하지 않음.

문제원인 : 아이폰과 안드로이드의 화면그리는 영역이 다름. 최상단을 SafeAreaView로 감싸고 있는데 이는 아이폰에만 적용되는 것. 아이폰은 상단 노치부분과 하단 home indicator 부분을 뺀 나머지 부분이 화면을 그리는 영역인데 안드로이드는 전체화면에 그림.
해결방법: useWindowDimensions()을 이용한 전체화면 height는 노치와 home indicator을 포함하여 나타냄. 때문에 아래와 같은 두가지 라이브러리를 설치하여 상태바(노치)의 높이와 인디케이터의 높이를 구해 전체 높이에서 뺀 값으로 계산을함.
```jsx
yarn add react-native-status-bar-height // 상태바 높이 구하는 라이브러리
yarn add react-native-iphone-x-helper //하단 인디케이터 높이 구하는 라이브러리
```
결과:

코드 변화:
전)

후)

# 문제상황2
목표: height - getBottomSpace() - getStatusBarHeight()의 크기가 안드로이드와 ios가 동일하게 잡히길 원함.
문제상황: height - getBottomSpace() - getStatusBarHeight()안드로이드는 전체영역에서 그려지기 때문에 getStatusBarHeight()의 값을 제거할 필요 없음. 현재는 함께 제거가 되기 때문에 아래와 같은 문제가 발생함.

해결방법: Platform을 구해 각각 height 로직을 적용함

```jsx
전)
height: height - getBottomSpace() - getStatusBarHeight()
후)
import {Platform} from 'react-native';
...
height: Platform.OS === 'ios'
? height - getBottomSpace() - getStatusBarHeight()
: height - getBottomSpace(),
```
# SafeAreaInsets 활용해 동적 스타일링
## 외부 라이브러리 도움 없이 하는 방법
이 동적 스타일링이 필요했던 가장 중점적 이유는
react-navigation을 사용할 때 헤더와 바텀 nav를 뺀 안쪽 공간을 동적으로 구하여 스타일링 해야하기 때문이다.따라서 PageTemplate 컴포넌트를 구현하여 페이지 root container로 감싸준다.
이러면 알아서 기기에 따라 그려지는 화면의 영역을 잡아준다.
```tsx
import {
useSafeAreaFrame,
useSafeAreaInsets,
} from 'react-native-safe-area-context'; // sateArea의 top, left, height width 등
import {useHeaderHeight} from '@react-navigation/elements'; //nav header 높이
export default (props: PropsWithChildren) => {
const {children} = props;
const {height} = useSafeAreaFrame(); // 유효한 전체 넓이
const {top, left} = useSafeAreaInsets();
const headerHeight = useHeaderHeight(); // 헤더
const dynamicStyles = styles(height - headerHeight, top, left);
return <View style={dynamicStyles.container}>{children}</View>;
};
const styles = (height: number, top: number, left: number) =>
StyleSheet.create({
container: {
width: '100%',
height: height,
paddingHorizontal: left + 10,
paddingVertical: top + 10,
backgroundColor: theme.color.white,
},
});
```
'FE 기술 > React Native' 카테고리의 다른 글
[React Native] React-Native-Cli 환경설정(MAC) + 환경설정 에러 관련 (1) | 2024.12.08 |
---|