감정일기(가칭)

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

밤새는 탐험가89 2025. 12. 10. 07:01
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