본문 바로가기
감정일기(가칭)

📘 감정일기 작성 화면에서 날짜 선택 UI는 어떻게 설계해야 할까?— 달력을 직접 넣을까, 시트로 띄울까? 구조적 고민과 결론 정리

by 밤새는 탐험가89 2025. 12. 10.
728x90
SMALL

 

감정일기를 작성하는 6단계 UI를 만들면서,
마지막 단계(6/6)에서 날짜 + 사진을 선택하는 화면을 구현해야 했다.

처음엔 단순히 UILabel로 “2025년 12월 10일” 같은 표시만 하고,
여기를 탭하면 날짜를 선택하게 만들면 되겠다고 생각했다.

문제는 날짜 선택 UI를 어떻게 노출할 것이냐였다.

 

1. 두 가지 설계안 비교하기

날짜를 선택하는 UI는 크게 두 방향으로 구현할 수 있었다.

Label을 탭 → Bottom Sheet → 달력 뷰 띄우기

(달력은 따로 만든 UICollectionView 기반 CalendarVC 사용)

이 방식은 카카오톡, 슬랙, 노션 등 대부분의 앱에서 사용하는 형태이다.
필요할 때만 달력이 화면에 나타나고, 선택하면 즉시 내려간다.

 

마지막 단계 셀 내부에 달력을 직접 넣기

(Cell 안에 UICollectionView를 그대로 넣어서 달력 UI 전체를 표시)

즉, DiaryWriteDateAndGalleryCell 내부 UI로 달력 전체가 들어가 버리는 구조다.

 

두 구현 모두 한 화면 안에서 날짜를 선택할 수 있다는 점에서는 동일하지만,
장기적인 유지보수와 UX 기준에서는 큰 차이가 있다.

 

2. 결론: 두 방식 중 정답은 ① Bottom Sheet 방식

간단히 말하면,

👉 Label을 탭하면 Bottom Sheet로 날짜 선택 화면을 띄우는 방식이 압도적으로 더 좋다.

왜 그런지 UI/UX · 아키텍처 · 성능 관점으로 하나씩 정리해보자.

 

3. 왜 Bottom Sheet 방식이 더 좋은가?

✔ 3-1. 현재 작성 단계UI 흐름과 가장 자연스럽게 맞기 때문

지금 감정일기 작성 UI는 총 6단계(step-by-step) 로 구성되어 있다.

  • emotion
  • situation
  • thought
  • reeval
  • action
  • dateAndImages ← 마지막 단계

여기서 갑자기 큰 달력 UI가 나타나면?

  • UI 맥락이 갑자기 바뀜
  • 마지막 단계가 "요약/완성" 느낌인데 갑자기 UI가 너무 무거워짐
  • 화면 높이를 차지하는 요소가 늘어나면서 스크롤이 길어짐

반대로,
“날짜를 선택하세요 → 라벨 표시 → 탭하면 달력”
이라는 구조는 작성 흐름을 전혀 방해하지 않음.

 

✔ 3-2. 달력을 셀 안에 넣는 것은 메모리·성능 측면에서 비효율적

내가 만든 달력은 UICollectionView 기반이라:

  • 월 데이터 모델
  • 날짜 셀 렌더링
  • 선택 상태 관리
  • diffable datasource 적용

이런 내부 로직이 이미 복잡하다.

이걸 DiaryWrite의 셀 안에 넣으면,

  • 셀 재사용 과정에서 상태 꼬일 위험
  • 스크롤 시 매번 달력 로직이 호출됨
  • 셀이 두 개만 있어도 달력 뷰가 여러 번 만들어짐
  • 메모리 사용량이 불필요하게 증가함

즉, 달력은 독립적인 ViewController로 다루는 것이 가장 합리적이다.

 

✔ 3-3. UX 측면에서도 Bottom Sheet가 더 익숙하고 부담이 없다

대부분의 앱이 날짜 선택을 아래 방식으로 처리한다:

  • iOS 기본 DatePicker → bottom sheet
  • 카카오톡 일정 → bottom sheet
  • 구글 캘린더도 modal/calendar picker 사용

사용자 입장에서도,
현재 화면을 유지한 채, 일부 UI만 위로 올려서 선택하는 구조
훨씬 자연스럽고 피로도가 낮다.

 

✔ 3-4. 유지보수 및 확장성이 훨씬 좋다

Bottom Sheet 방식의 핵심 장점:

  • CalendarViewController를 재사용 가능
  • 다른 기능에서도 날짜 선택 UI가 필요하면 그대로 이용 가능
  • 작성 화면과 달력 로직이 깔끔히 분리됨
  • MVVM 구조에 맞게 역할 분리가 쉬움

반대로 셀 내에 달력을 넣으면:

  • 로직이 뭉치고
  • 셀의 책임 범위가 비대해지고
  • 기능 확장이 매우 어렵다

4. 실제 구현 구조 (추천 아키텍처)

4-1. Cell(마지막 스텝)의 역할

  • 현재 선택한 날짜 표시(label)
  • label 탭 → onTapDatePicker 콜백 호출
var onTapDatePicker: (() -> Void)?

 

4-2. ViewController의 역할

  • label 탭 시 → Bottom Sheet 띄우기
cell.onTapDatePicker = { [weak self] in
    self?.presentDatePickerSheet()
}

 

4-3. CalendarViewController의 역할

  • 달력 UI 그리기
  • 날짜 선택 후 onDateSelected 호출
var onDateSelected: ((Date) -> Void)?

 

4-4. 선택된 날짜가 오면 ViewModel에 저장

datePicker.onDateSelected = { [weak self] date in
    self?.viewModel.updateDate(date)
    self?.reloadCell(for: .dateAndImages)
}

 

 

5. 실제 앱 흐름 예시

[감정일기 작성 6단계 화면]
     ⬇
[날짜 라벨 탭]
     ⬇
[Bottom Sheet로 달력 띄움]
     ⬇
[날짜 선택 → sheet 닫힘]
     ⬇
[Cell 라벨 자동 업데이트]

 

6. 최종 결론

달력을 직접 셀에 넣는 방식
→ UI 무거워짐 · 메모리 비효율 · 재사용 문제 · 구조 복잡

Label + Bottom Sheet 방식(달력은 독립 VC)
→ UI 깔끔 · UX 친숙 · 유지보수 쉽고 확장성 높음 · 아키텍처적으로도 정석

따라서 감정일기 작성 마지막 단계에서
날짜 선택 UI를 구현할 때는,

🎯 “라벨을 탭하면 Bottom Sheet로 달력 ViewController를 띄우는 방식을 사용한다.”

728x90
LIST