본문 바로가기

MAUI CollectionView 셀 재활용과 부분 업데이트 문제 완전 분석

@veedeeo 2025. 12. 13. 20:11

MAUI CollectionView는 모바일 UI 구성에서 매우 강력한 도구이지만 실제 개발에서는 예상치 못한 문제를 자주 발생시킨다. 그중에서도 가장 흔한 오류는 부분 업데이트(partial update) 또는 컬렉션 항목 변경 시 UI가 불안정하게 재생성되는 현상이다.
오늘은 이 메커니즘을 가장 깊이 있게 정리한다.

 

Minimalist MAUI CollectionView Banner


1 왜 부분 업데이트가 문제를 일으키는가?

CollectionView는 성능 최적화를 위해 내부적으로 가상화(virtualization)셀 재활용(cell recycling) 구조를 사용한다.
이 구조는 메모리를 절약하고 스크롤 성능을 개선하지만 다음과 같은 부작용도 함께 발생한다.

1 새로운 항목이 추가되면 기존 셀도 재배치됨

하나의 항목을 삽입하면 CollectionView는 전체 렌더링을 최소화하기 위해 셀을 재활용하며 화면을 다시 구성한다.
이 과정에서 아래와 같은 문제들이 나타난다.

  • 이전 항목의 상태가 새 셀에 남아 있음
  • 체크박스가 이상한 값으로 초기화됨
  • 스크롤하거나 값만 바꿨는데 UI가 깜빡임
  • 특정 셀만 업데이트했는데 전체 UI가 리셋되는 것처럼 보임

부분 업데이트는 실제로 부분만 바꾸지 않는다. 내부적으로는 전체 리스트의 렌더링 경로를 재배치하는 방식으로 처리된다.

2 ObservableCollection.CollectionChanged 이벤트의 동작 방식 때문

ObservableCollection에서

  • Add
  • Insert
  • Remove
    이 이벤트가 발생하면 CollectionView는 Template을 재활용하고 필요 시 재렌더링을 요청한다.

즉 ObservableCollection은 항목 변경 = 셀 재활용 트리거다.

3 DataTemplate이 “상태 있는 UI”를 갖고 있을 때 문제가 커짐

예를 들어 셀 내부에

  • CheckBox
  • RadioButton
  • Switch
  • Slider

같은 상태 기반 UI가 있다면 셀 재활용 시 이전 상태가 그대로 끌려온다.
이 구조에서 가장 흔한 버그는 다음과 같다.

  • 체크가 안 풀림
  • 체크박스가 다른 항목의 상태를 그대로 부착
  • UI는 변했는데 실제 Model 속성은 변화 없음
  • Model은 바뀌었는데 UI 반영이 늦게 되거나 건너뜀

MAUI 초기 개발자 80%가 바로 이 문제를 겪는다.


2 부분 업데이트 문제로 실제 개발자가 겪는 대표 증상

다음 상황이 하나라도 있다면 CollectionView 내부에서 셀 재활용 이슈가 발생했다고 보면 거의 맞다.

1 UI 상태가 항목 순서에 따라 바뀌어버림

스크롤을 아래까지 내린 후 다시 위로 올리면
체크박스, 이미지, 배경색 등이 바뀌어 있다.

2 선택 상태가 항목 변경 때마다 초기화됨

예를 들어 음악 재생목록 UI에서 항목을 하나 삭제했더니
위에서 체크했던 항목들이 모두 풀려버리는 현상.

3 Add 후 UI가 순간적으로 깜빡임 또는 렉 발생

특히 모바일(Android)에서 더 자주 발생한다.

4 항목을 빠르게 추가하면 UI가 전혀 다른 값을 표시


재생목록 전체 업데이트, 스크롤 동안 항목이 점프하면서 보임.

이런 증상은 MAUI CollectionView의 구조를 이해하면 정확한 원인 분석이 가능하다.


3 내부 메커니즘을 기반으로 문제 원인을 단계적으로 분석하기

1 단계

DataTemplate이 재활용될 때 BindingContext 변경 시점 확인
이 시점에 UI가 잘못 초기화되면 모든 문제가 여기서 시작된다.

2 단계

INotifyPropertyChanged의 정확한 구현 확인
UI가 Model을 따라가야 하는데 이벤트가 발생하지 않으면 UI만 변경된다.

3 단계

CollectionChanged 이벤트가 너무 자주 발생하는지 체크
특히 다음과 같은 패턴은 거의 반드시 문제를 만든다.

PlaylistItems = new ObservableCollection<PlaylistItem>(newList);
 
 

이렇게 전체 리스트를 매번 새로 만드는 것은 최악의 패턴이다.
MAUI는 이를 전체 리스트 변경으로 처리하며 모든 셀을 재활용한다.
따라서 UI가 계속 깜박인다.

4 단계

Add, Remove, Insert 등 변경 연산 후 UI 초기화가 필요한지 확인
예를 들어 CheckBox는 바인딩만 믿고 초기화를 안 하면
재활용 셀에서 상태가 남아 있는 경우가 생긴다.


4 부분 업데이트 문제를 해결하는 실전 패턴 7가지

이번 섹션은 많은 MAUI 개발자들이 실제 프로젝트에서 사용하고 안정성을 검증한 패턴들로 구성했다.


1 패턴 상태값을 UI가 아니라 Model에서만 관리

절대 UI에서 직접 체크를 조작하고 Model을 나중에 반영하는 식으로 하지 않는다.

정답 패턴

<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}" />
 
 

그리고 Model의 IsSelected는 반드시 PropertyChanged를 포함해야 한다.


2 패턴 SelectionMode="None" 고정

CollectionView 기본 선택 모드와 체크박스 기반 선택 로직은 절대 함께 쓰지 않는다.

<CollectionView SelectionMode="None" />
 
 

모든 선택은 Model.IsSelected로 통일하는 것이 가장 안정적이다.


3 패턴 항목 대량 변경 시 Replace 대신 Add/Remove 활용

아래 코드는 절대 사용하지 않는다.

PlaylistItems = new ObservableCollection<PlaylistItem>(results);
 
 

반드시 아래처럼 사용해야 한다.

PlaylistItems.Clear();
foreach (var item in results)
    PlaylistItems.Add(item);
 
 

이렇게 하면 셀 재생성 없이 변경만 반영되므로 UI가 안정적이다.


4 패턴 BindingContext 변경 시 UI 초기값을 확실하게 설정

DataTemplate의 상태가 재활용되지 않도록 한다.


셀 초기 배경색을 조건 기반으로 설정

<Border BackgroundColor="{Binding IsSelected, Converter={StaticResource BoolToColor}}" />

5 패턴 항목 갱신 시 Device.BeginInvokeOnMainThread 활용

UI 렌더 타이밍 충돌을 방지한다.


6 패턴 ObservableCollection 대신 List를 사용하는 구간을 분리

대량 업데이트는 List로 만들고
최종 단계에서 ObservableCollection에 반영한다.


7 패턴 CollectionView의 VerticalItemSpacing, Margin 조정

부분 업데이트 때 발생하는 레이아웃 점프 현상을 줄인다.

 
<CollectionView VerticalItemSpacing="4" />

5 실제 프로젝트에서 제일 많이 쓰이는 안정 구조

많은 개발자들이 공통적으로 결론 내리는 안정 구조는 다음과 같다.

1 항목 전체를 새로 만드는 Replace 패턴 사용 금지
2 SelectionMode는 None
3 CheckBox는 반드시 TwoWay
4 Model이 상태를 다 관리
5 CollectionView는 단지 보여주는 역할만 수행
6 대량 업데이트는 Clear 후 Add 방식으로만 수행
7 UI 깜빡임은 DataTemplate 초기화가 핵심 원인

이 구조를 지키면
체크 꼬임
스크롤 오류
셀 재활용 문제
렌더링 깨짐
깜빡임
이 현상들은 대부분 사라진다.

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

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

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

목차