728x90
SMALL
1️⃣ 감정 선택 UI 구조 설계
1. EmotionCategory 목록 표시
- Calendar처럼 유저가 선택해야 하는 감정 카테고리(예: 행복, 슬픔, 분노 등)를 카드 형태로 2열 Grid로 표시.
- 각 카테고리는 emoji + displayName + 배경색을 가짐.
- 처음에는 카테고리 카드만 보임.
2. 카테고리 확장(Expand)
- 유저가 카테고리 카드 하나를 탭하면:
- 해당 셀이 확장되어(subContainer visible) 하위 감정 목록(subEmotions)을 버튼 형태로 보여줌.
- 다른 카테고리가 열려 있었다면 자동으로 닫힘.
- 확장된 카테고리 안에는 subEmotion 버튼이 리스트로 구성됨.
3. subEmotion 선택 UI
- subEmotion은 선택 버튼(UIButton) 형태로 제공.
- 선택 시:
- 탭한 버튼 색상/선(Border) 변경으로 “선택됨” 표시.
- 하지만 UI 업데이트는 StepCell이 최종 허가를 내린 뒤에만 적용됨.
2️⃣ 감정 선택 흐름 설계(이벤트 흐름)
1) 유저가 subEmotion 버튼을 탭함
- EmotionCategoryCell은 내부 상태를 바꾸지 않고
“이 emotion 항목이 눌렸음"이라는 이벤트만 Bubble Up 함.
Reason → MVVM의 단방향 데이터 흐름 준수
2) EmotionStepCell에서 로직 처리
EmotionStepCell은 다음을 수행:
- 현재 선택 상태(selectedSubEmotions) 조회
- candidate(가상의 선택 결과) 생성
- 포함되어 있으면 제거
- 없으면 추가
- ViewModel에 candidate가 가능한지 물어봄
let result = viewModel.trySelectEmotion(candidate)
3) ViewModel은 선택 행위를 검증(유효성 검사)
ViewModel에서는 아래 규칙을 검사함:
- 최대 3개 선택 여부
- 다른 카테고리와 섞어 선택하는지
- 0개 선택은 허용되지만 “next step"에서는 사용될 예정
- 문제가 있으면 errorMessage Publish → VC가 Alert 표시
4) StepCell이 검증 결과에 따라 UI 처리
- ❌ 검증 실패: UI 업데이트 없음
- ⭕ 검증 성공:
- StepCell 내부의 selectedSubEmotions 업데이트
- 해당 CategoryCell만 reload하여 UI 업데이트
- ViewModel의 editableDiary.emotion에 반영
3️⃣ MVVM 책임 분배 설계
✔ EmotionCategoryCell
- UI 컴포넌트
- 선택된 항목 표시/버튼 생성
- 내부에서 상태 바꾸지 않음
- 오직 “어떤 subEmotion 버튼이 눌렸는지"만 상위로 전달
✔ EmotionStepCell
- 이 단계의 로컬 상태 관리 (selectedSubEmotions)
- UI 갱신 주도 (reloadItems)
- ViewModel과 상호작용
- CategoryCell에 선택 상태 전달
✔ DiaryWriteViewModel
- 비즈니스 로직 계층
- 감정 선택 유효성 검사(trySelectEmotion)
- 다음 단계 이동 유효성 검사(canProceedToNextStep)
- editableDiary 업데이트 관리
- errorMessage Publish
✔ DiaryWriteViewController
- ViewModel의 errorMessage를 받아 Alert 표시
- onTapPrev / onTapNext 페이지 전환 관리
- next 단계 이동 가능한지 ViewModel에 확인 후 이동
4️⃣ 유효성 검사 설계(Validation Logic)
A. 감정 선택 시 유효성 검사 (trySelectEmotion)
- subEmotion이 4개 이상이면 → 선택 불가
- 감정 카테고리가 이미 정해져 있고, 다른 카테고리의 감정을 선택하려 하면 → 선택 불가
- 그 외에는 선택 허용
문제 발생 시:
- errorMessage Publish
- StepCell이 UI 업데이트 하지 않음
B. 다음 단계로 이동할 때 유효성 검사(canProceedToNextStep)
- Step == .emotion 일 때:
subEmotion이 0개이면 → 이동 불가 + Alert
- Step == .situation/thought/action 에서는 텍스트 입력 여부 확인 가능
5️⃣ 예외 상황 처리(UX 관점의 설계)
❌ subEmotion 4개 선택하려 하면?
- ViewModel → false
- errorMessage 발생
- Alert 표시
- UI 변화 없음
❌ 감정 선택 안 한 채 next 버튼 눌렀을 때?
- canProceedToNextStep(.emotion)에서 false
- “최소 1개 선택하세요” Alert
- 이동하지 않음
✔ 선택 상태 변경 후 셀 자동 업데이트
- StepCell이 reloadItems(at:) 수행
- CategoryCell이 configure를 통해 최신 상태 표시
6️⃣ 확장성 고려 설계
- Situation/Thought/Reeval/Action 단계도
동일한 검증 구조(canProceedToNextStep)로 확장 가능 - 감정 선택 상태는 ViewModel에서 중앙 관리하므로
이 데이터는 어디에서든 읽을 수 있음 - 감정 선택 UI/Cell이 강하게 결합되지 않아
추후 디자인 변경에도 손쉽게 대응 가능
728x90
LIST
'감정일기(가칭)' 카테고리의 다른 글
| 📘 DiaryWriteViewController 설계 문서 (함수·프로퍼티 단위 상세 버전) (0) | 2025.12.09 |
|---|---|
| 📘 DiaryWriteViewModel – 설계 문서 (Logic Blueprint) (0) | 2025.12.09 |
| ❌ 한 셀만 열리고, 나머지는 닫히는 상태(sync)가 유지되지 않는다... (0) | 2025.12.08 |
| 🤔 왜 지금 애니메이션이 딱딱하게 보이고, fade-in/fade-out이 안 보이는지, 그리고 정확한 해결 방법까지 아주 명확히 설명 (0) | 2025.12.08 |
| 🧠 EmotionCategoryCell 완전 이해하기 (0) | 2025.12.08 |