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

❌ 한 셀만 열리고, 나머지는 닫히는 상태(sync)가 유지되지 않는다...

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

✔ 지금 왜 이런 문제가 생겼는가?

기존에는 reloadData()가 실행되면:

  • 모든 셀 configure()가 무조건 다시 불림
  • expandedCategory를 기준으로 열리고/닫힘이 일관되게 적용됨
    → 그래서 항상 한 셀만 열려 있었음

하지만 지금은:

  • 새로 클릭한 셀만 animateToggle 실행
  • 이전에 열려 있던 셀은 그냥 “열린 채” 화면에 남아 있음
  • configure()가 다시 호출되지 않기 때문

즉, 셀 A가 열려 있고 셀 B를 누르면:

  • B는 animateToggle(expanded: true)로 열림
  • A는 닫히라는 명령을 받지 못함 → 그대로 열려 있음

그래서 “둘 다 열린 상태”가 되어버리는 것.

 

✔ 해결 방법

✅  "이전 열린 셀만" 다시 업데이트하기 (가장 좋은 방법)

우리가 이전에 열려 있던 셀의 indexPath를 알고 있다면
그 셀만 애니메이션으로 닫아주면 됨.

🔧 Step 1: EmotionStepCell에 이전 index 저장

private var expandedCategory: EmotionCategory?
private var expandedIndexPath: IndexPath?

 

🔧 Step 2: didSelectItem에서 처리

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    let category = categories[indexPath.item]

    let previousIndexPath = expandedIndexPath  // ★ 저장

    if expandedCategory == category {
        // 접기
        expandedCategory = nil
        expandedIndexPath = nil
    } else {
        // 새 카테고리 펼치기
        expandedCategory = category
        expandedIndexPath = indexPath
    }

    // 레이아웃 변경
    collectionView.performBatchUpdates(nil)

    // ★ 현재 선택한 셀 애니메이션
    if let cell = collectionView.cellForItem(at: indexPath) as? EmotionCategoryCell {
        cell.animateToggle(expanded: expandedCategory == category)
    }

    // ⭐ 이전에 열려 있던 셀 닫기
    if let prev = previousIndexPath,
       prev != indexPath,
       let previousCell = collectionView.cellForItem(at: prev) as? EmotionCategoryCell
    {
        previousCell.animateToggle(expanded: false)
    }
}

 

 

🎉 이 방법의 장점

  • reloadData() 없이도 부드러운 fade-in/out 유지
  • 오직 2개 셀만 다시 그려서 효율적
  • 성능 최상
  • UI 애니메이션이 자연스러움

 

 

728x90
LIST