React Native에서 iOS 13 다크모드 대응하기
문제 상황
iOS 13이 출시되면서 사용자들이 다크모드 설정을 켜놓은 상태에서 앱을 실행하면 의도하지 않은 색상으로 UI가 표시되는 이슈가 발생했다. 특히 StatusBar와 네이티브 컴포넌트들이 시스템 테마를 따라가면서 기존 디자인과 충돌했다.
임시 해결: 다크모드 비활성화
우선 iOS에서 다크모드를 강제로 비활성화하는 방법을 적용했다.
Info.plist에 다음을 추가:
<key>UIUserInterfaceStyle</key>
<string>Light</string>
이렇게 하면 시스템 설정과 무관하게 항상 라이트모드로 고정된다.
제대로 된 대응
하지만 장기적으로는 다크모드를 지원하는 게 맞다고 판단했다. react-native-appearance 라이브러리를 사용해서 시스템 테마를 감지하도록 구현했다.
npm install react-native-appearance
cd ios && pod install
import { useColorScheme } from 'react-native-appearance';
const MyComponent = () => {
const scheme = useColorScheme();
const backgroundColor = scheme === 'dark' ? '#000' : '#fff';
const textColor = scheme === 'dark' ? '#fff' : '#000';
return (
<View style={{ backgroundColor }}>
<Text style={{ color: textColor }}>Hello</Text>
</View>
);
};
Theme Provider 구성
전역적으로 테마를 관리하기 위해 Context API를 활용했다.
const ThemeContext = React.createContext();
export const ThemeProvider = ({ children }) => {
const scheme = useColorScheme();
const theme = scheme === 'dark' ? darkTheme : lightTheme;
return (
<ThemeContext.Provider value={theme}>
{children}
</ThemeContext.Provider>
);
};
Styled-components도 고려했지만 React Native 0.60에서 아직 퍼포먼스 이슈가 있어서 일단은 plain object로 관리하기로 했다.
남은 과제
- 이미지 에셋도 다크모드 버전이 필요함
- Android 10 Q 베타의 다크모드도 곧 대응 필요
- 사용자가 앱 내에서 테마 선택할 수 있는 옵션 추가 검토중