본문 바로가기
🍎 iOS/문서읽기

[UIKit] UITableViewDiffableDataSource ( iOS 13.0+ )

by @Eddy 2023. 7. 30.
728x90

Notion에 정리한 내용을 옮겨왔다.

 

UITableViewDiffableDataSource

공식문서에서는 다음과 같이 설명한다.

  • DataSource의 특수한 형태
  • 간단하고 효율적인 방식으로 view의 데이터와 UI를 업데이트 관리하는 데 필요한 동작 제공
  • UITableViewDataSource 프로토콜에서 제공하는 모든 메서드 구현 제공
  • TableView에 DiffableDataSource를 연결하려면, cellProvider initializer를 이용해 DiffableDatasource를 만들어 연결하려는 tableView에 전달하면 된다.
  • 그뒤에 snapshot을 구성하고 적용해, Data의 현재 상태를 생성하고, UI에 데이터를 표시한다.
dataSource = UITableViewDiffableDataSource<Int, UUID>(tableView: tableView) {
    (tableView: UITableView, indexPath: IndexPath, itemIdentifier: UUID) -> UITableViewCell? in
    // configure and return cell
}

주의 사항

  • diffableDataSource로 구성한 후에는 dataSource를 변경해선 안 된다.
  • 초기화 후 새로운 DataSource가 필요하다면, 새로운 TableView와 diffableDataSource를 생성하고 구성해야 한다.

 

NSDiffableDataSourceSnapshot

공식문서에서는 다음과 같이 설명한다.

  • 특정 시점의 뷰에 있는 data의 상태 표현 → 즉, Data에 따라 view가 실시간으로 수정되지는 않음.
  • view가 표시하는 데이터의 초기 상태를 설정하기 위해 사용
  • view가 표시하는 데이터의 변화를 반영하기 위해 사용
  • Section과 Item은 Hashable Protocol을 수행하는 유일 식별자(unique identifier)를 가져야한다.
  • 식별자로 Int, String, UUID같은 기본 제공 유형을 포함해 struct나 enum같은 value type을 사용해라.
  • 만약 식별자로 class를 사용한다면 해당 클래스는 NSObject의 서브클래스여야 한다.

사용법은 아래와 같다.

  1. 빈 snapshot을 생성하고, snapshot에 sections과 items를 append한다
  2. diffableDataSource.snapshot()을 호출해 현재의 snapshot을 얻고, 표시하려는 데이터의 새로운 상태를 반영하기 위해 snapshot을 수정해라.
  3. snapshot 생성에 대한 예제 코드는 다음과 같다.
// Create a snapshot.
var snapshot = NSDiffableDataSourceSnapshot<Int, UUID>()        

// Populate the snapshot.
snapshot.appendSections([0])
snapshot.appendItems([UUID(), UUID(), UUID()])

// Apply the snapshot.
dataSource.apply(snapshot, animatingDifferences: true)

 

Reconfigure와 Reload의 차이

DiffableDataSource에는 reconfigureItems와 reloadItems가 있다.

reconfigureItem은 기존 셀은 보존한 채, 해당 셀을 업데이트를 하는 개념이지만,

reloadItem은 해당 셀을 새로 불러온다는 개념으로 차이가 있다.

UIKit 팀의 Tylor Fox도 reconfigure와 reload의 차이를 설명했다. (출처)

  • 번역
    • Reload: 기존의 cell을 새 cell로 바꾼다.왜냐하면 Reconfigure는 새 cell을 요청하거나 만들지 않아 훨씬 효율적이기 때문이다.
    • Reconfigure: 직접 기존 cell을 업데이트할 수 있다.
    • Reconfigure가 Reload보다 가벼운 버전인데, 그 이유는 아래와 같다.
  • 원문
    • Reload: replaces the existing cell with a new cell.Because reconfigure doesn’t request/create a new cell, it’s significantly more efficient!
    • Reconfigure: allows you to directly update the existing cell.
    • You can think of reconfigure as a lighter-weight version of reload.

 

경험한 문제

  1. DiffableTableView의 Cell간격은 어떻게 제어하는가
    • contentView.frame = contentView.frame.inset(by: UIEdgeInsets())을 통해 다뤄도 되지만, 잘 못다루는 것인지 cell 내부의 View들의 높이에도 영향을 줬으며, contentView 자체의 cornerRadius에도 영향을 줬다.
    • 그래서 constraint로 직접 cell 내부 view의 사이즈를 조정했다.
  2. DiffableTableView의 기본 소스코드는 어떻게 될까?
    • 기본 소스코드는 DiffableTableView를 사용 후 느낀바를 정리하면서 같이 기록했다.
  3. DiffableTableView에서 Cell Index을 어떻게 알 수 있는가?
    • let index = dataSource.indexPath(for: item) 을 이용해 구할 수 있다.
    • 각각의 cell에 어떤 속성을 적용하기 위한 코드는 datasource의 UITableViewDiffableDataSource<MemoList, Datum>(tableView: self.tableView, cellProvider: { tableView, indexPath, data -> UITableViewCell? in 를 이용하면 되지만, 직접적으로 Cell의 Index를 다룰 때에는 위와같은 방법이 필요하다.

 

참고자료

반응형

'🍎 iOS > 문서읽기' 카테고리의 다른 글

[SwiftUI] @State, @Binding  (0) 2024.01.07
[Article - UITableView] Filling a table with data  (0) 2023.07.28
[UIKit] UITableView의 구조  (0) 2023.07.28
[UIKit] UITableViewCell의 구조  (0) 2023.07.28
[H.I.G] Designing for iOS 번역  (0) 2023.07.01

댓글