본문 바로가기

MAUI CollectionView에서 항목 삭제 시 UI가 비정상적으로 갱신되거나 체크 상태가 섞이는 문제의 근본 원인과 해결 전략

@veedeeo 2025. 12. 12. 14:04

MAUI로 앱을 개발하다 보면 CollectionView 내부에서 항목을 삭제했을 때 UI가 예상과 다르게 갱신되는 문제가 자주 발생합니다. 특히 재생목록, 파일 리스트, 옵션 선택 메뉴처럼 ‘선택 상태를 유지해야 하는 UI’를 구현할 때는 다음과 같은 문제가 많이 보고됩니다

  • 특정 항목을 삭제했더니 아래 항목의 체크 여부가 위로 복사됨
  • 삭제 직후 화면이 깜빡이며 템플릿이 이상하게 재배치됨
  • ObservableCollection에서 Remove 했는데 UI는 삭제되지 않거나 반응이 느림
  • 체크했던 항목이 삭제 후 엉뚱한 위치로 이동해 보임
  • SelectionMode와 ItemTemplate의 바인딩이 충돌해 삭제 후 UI가 재렌더링됨
  • 삭제한 항목 직후의 셀에서 클릭 이벤트가 먹지 않음

이 문제는 단순히 “UI 업데이트가 안 된다” 수준이 아니라
MAUI CollectionView의 가상화, 템플릿 재사용, BindingContext 재주입 구조가 한 번에 흔들리면서 발생하는 복합적 구조 문제입니다. 이번 글에서는 MAUI CollectionView에서 항목 삭제 시 UI가 비정상적으로 동작하는 원리를 깊이 있게 분석하고, 실제 앱 개발자가 실무에서 바로 적용할 수 있는 해결책을 제시합니다.

 

MAUI CollectionView Deletion Diagram


1. 항목 삭제 직후 체크 상태가 섞이는 이유 — 템플릿 재사용이 즉시 발생하기 때문

CollectionView에서 항목을 삭제하면
해당 위치 아래의 셀(template)이 순식간에 한 칸씩 위로 올라옵니다.

이 과정은 내부적으로 다음 순서로 진행됩니다

  1. ObservableCollection.Remove(index) 호출
  2. UI는 index 이후의 셀들을 새 BindingContext로 교체
  3. 템플릿 재사용 최적화가 작동
  4. 기존 UI 내부 상태가 초기화되지 않은 채 연결됨
  5. CheckBox 상태가 이전 항목의 UI 상태를 그대로 가짐

따라서 항목 삭제 시 CheckBox가 다른 항목의 체크 상태를 복사한 것처럼 보이는 현상이 발생합니다.

이것은 MAUI의 버그가 아니라,
성능 최적화를 위한 템플릿 재사용 구조가 제대로 된 MVVM 패턴 없이 사용될 때 나타나는 자연스러운 현상입니다.


2. 삭제 직후 UI가 깜빡이거나 재구성되는 이유 — 내부 Diff 알고리즘의 한계

MAUI CollectionView는 내부적으로 데이터 변경을 감지할 때 “Diff-like 갱신 알고리즘”을 사용합니다.
문제는 이 알고리즘이 리스트의 중간에서 항목이 제거되는 상황에 완벽히 대응하지 못한다는 것입니다.

즉,

  • 삭제 전 상태
  • 삭제 후 상태
    두 상태를 비교해 최소 변경만 UI에 반영해야 하지만
    템플릿 재활용 때문에 실제로는 많은 셀이 재구성되며 깜빡임 현상이 발생합니다.

특히 Android 환경에서 더 심합니다

  • RecyclerView 기반으로 동작
  • 레이아웃 측정(Layout Measure) 단계가 여러 번 실행됨
  • 삭제 후 높이 계산이 재시작되면서 화면이 순간적으로 튐

이러한 문제는 MAUI 구조적 한계에 가깝기 때문에
UI 상태 대신 데이터 기반 상태 관리로 해결해야 합니다.


3. 삭제한 항목 아래의 셀에서 클릭 이벤트가 먹히지 않는 이유

이 문제는 하위 셀이 강제로 리바인딩되면서
GestureRecognizer 또는 Tap 이벤트가 상위 Grid에서 걸려 있기 때문에 발생하는 현상입니다.

삭제 후 셀 템플릿이 새 항목을 위한 BindingContext로 교체되는 순간
기존에 연결된 GestureRecognizer 객체가 그대로 남아 있고
CheckBox보다 먼저 터치 이벤트를 소비합니다.

따라서

  • CheckBox가 클릭되지 않거나
  • Text 클릭 시 이상한 셀이 선택되는 현상이 발생합니다.

이는 데이터와 UI 이벤트가 분리되어 MVVM이 아닌 구조에서 더 자주 발생합니다.


4. 삭제 후 비정상 동작을 막으려면 MVVM을 반드시 준수해야 함

CollectionView는 MVVM 기반 컨트롤입니다.
UI 상태(체크 여부, 선택 여부)를 UI 내부 요소에 저장하면
삭제, 스크롤, 필터링 등 리스트 구조가 바뀌는 순간 상태가 모두 깨집니다.

따라서 다음 원칙을 반드시 지켜야 합니다

  • 체크 상태는 데이터 모델의 IsSelected에만 저장
  • UI의 CheckBox는 항상 그 값을 그대로 표시만 함
  • 항목 삭제 시 VM의 항목 모델이 즉시 갱신되도록 PropertyChanged 필수
  • UI는 ObservableCollection을 구독해 자동 업데이트

특히 중요한 점
UI 자체에 있는 CheckBox.IsChecked 값을 사용하면 무조건 오류가 생긴다.
데이터 기반이 아닌 UI 기반 상태 관리의 대표적인 실패 사례입니다.


5. 삭제 후 체크 상태가 섞이지 않게 하는 두 가지 필수 해결책

✔ 해결책 1: IsChecked를 ViewModel 속성에만 바인딩

UI 상태 저장 금지
모든 체크 상태는 VM에서 관리해야 합니다.

<CheckBox IsChecked="{Binding IsSelected}" />
 
 

✔ 해결책 2: Remove 후 SelectedItem 초기화

CollectionView는 내부 SelectedItem을 유지하려고 하기 때문에
삭제 시 인덱스가 밀리면서 엉뚱한 항목을 선택한 것처럼 보일 수 있습니다.

 
collectionView.SelectedItem = null;

✔ 해결책 3: 삭제 후 Task.Delay(10) 활용 (Android 한정)

Android 렌더링 타이밍 문제를 회피하기 위해 사용합니다.

 
Items.Remove(item);
await Task.Delay(10);
collectionView.SelectedItem = null;
 
 

아주 작은 지연이지만
실제로 많은 MAUI 개발자들이 겪는 삭제 후 UI 깨짐 현상을 완화합니다.


6. 항목 삭제 후 깜빡임 없이 자연스럽게 동작하게 만드는 고급 전략

여기부터는 실무 개발자들이 쓰는 전략입니다.

✔ 전략 1: Delete Animation 구현

삭제 즉시 UI를 갱신하지 않고 애니메이션 주기로 완화시키면
깜빡임이 거의 보이지 않게 됩니다.

✔ 전략 2: Template size 고정

셀 높이가 일정하면 삭제 후 템플릿 재측정이 줄어들어 깜빡임이 사라집니다.

✔ 전략 3: CollectionView 대신 ListView 사용 검토

Android에서 삭제 빈도가 많다면 오히려 안정적일 수 있음
다만 성능은 CollectionView가 더 우수

✔ 전략 4: 삭제 버튼을 개별 셀에서 제거, 상단 메뉴로 이동

셀 내부의 Button이 재활용되면서 이벤트가 꼬이는 현상을 줄임


종합 결론

MAUI CollectionView에서 항목 삭제 시
체크 상태가 섞이거나 UI가 비정상적으로 동작하는 문제는
단순 버그가 아니라 CollectionView의 기본 구조인
템플릿 재활용 + BindingContext 재배치 + 상태 기반 UI 컨트롤의 의존성 문제가 원인입니다.

이 문제는

  • MVVM 구조 준수
  • ViewModel을 단일 상태 저장소로 사용
  • 템플릿 재사용을 고려한 UI 설계
  • 삭제 후 SelectedItem 초기화
    이 네 가지를 지키면 대부분 해결됩니다.
veedeeo
@veedeeo :: .net MAUI·Netlify·SEO·웹 최적화 기술 블로그

.net MAUI·Netlify·SEO·웹 최적화 기술 블로그

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차