React-Native Time Picker 만들기 — 1

서론

Soen
roubit.me
8 min readApr 20, 2022

--

신규 앱을 만들면서 새로운 컴포넌트를 여러 개 만들게 되었다.
TimePicker도 그 중 하나였다. 라이브러리를 사용하는 방법도 있지만 애니메이션 연습하는 겸, 직접 컴포넌트들을 만들어보기로 했고 그 내용을 작성해보려고 한다.

구글링을 통해 [React-Native] Scrollable Time Picker 만들기(1) 를 읽고,
방향성을 잡는데 큰 도움을 받았다.

문제 & 목표

목표 스위치 디자인

과거에 사용하던 TimePicker는 datetimepicker 라이브러리였다.
Spinner 옵션을 주면 원하는 디자인/기능과 비슷하게 구현이 가능했었는데, 스피너가 완전히 멈춰야 값이 반영이 되는 식으로 구현이 되어 있어서 사용성에서 좋지 못하다고 판단했다.
- 상식적인 수준에서의 Spinner Time Picker
- 스피너가 도는 동안에도 값을 넘겨주는 것

을 목표로 컴포넌트를 작성했다.

작성

컴포넌트 구성
서론에서 언급한 것처럼 기본 큰 틀은 `bang9dev`님의 구조를 따른다.

세로로는 3개의 스크롤뷰를 배치하고( = 빨간색으로 표시된 박스),

그 위에 터치를 무시하는 `Overlay` 뷰 (녹색 반투명 박스)를 하나 씌운다.
이 TimePicker에서는 하늘색 박스 부분에 화살표 방향으로 그라데이션을 줘서 자연스레 사라지게 하고, 주황색 박스로 구분자를 주는 식으로 구현했다.

구현

먼저 빨간 박스를 먼저 구현해보도록 하자.
빨간 박스는 같은 속성을 가지는 `ScrollView` 다.

이 `ScrollView` 가 가져야 할 속성은 다음과 같다.

1. 각 인덱스마다 하나씩 걸리면서 스크롤되어야 한다.
2. 현재 보고 있는 인덱스 정보를 상위 컴포넌트로 넘겨줘야 한다.
3. 값을 수정하는 경우, 기존 값으로 보여야 한다.
4. 컴포넌트의 상위 객체에서 스크롤이 가능할 수도 있으므로 NestedScroll이 가능해야 한다.

해결 방법은 다음과 같다.

1. snapToInterval을 각 한 시각 단위의 높이로 넘겨줘서 해결.
2. onScroll Callback을 넘겨주는 것으로 해결.
3. contentOffset을 상위 컴포넌트에서 제공하는 것으로 해결.
4. iOS는 기본값이 true이므로 해당 사항 없고, 안드로이드는 nestedScrollEnabled를 true로 하는 것으로 해결.

다음으로는 TimePicker의 전체 컨테이너를 만들어보자.
이 컨테이너에는 앞서 만든 빨간 박스 스크롤 뷰 3개와 이후 만들 녹색 반투명 오버레이 뷰 1개가 들어갈 것이다.

--

--