본문 바로가기
이모저모/UIKit

다양한 셀을 그리는 DiffableDataSource 데이터 구성하기 #1

by ARpple 2023. 11. 10.

기초 DiffableDataSource

DiffableDataSource의 가장 큰 장점은 Snapshot을 이용해 수 많은 데이터 처리에 용이하다는 점이다.
⇒ 특히 렌더링 퍼포먼스를 애플이 최적화함

DiffableDataSource를 가장 쉽게 사용하는 방법은 다음과 같다.


struct MusicItem:Identifiable,Hashable{
    var id = UUID()
    var artist = "Newjeans"
}
struct ShortVideo:Identifiable,Hashable{
    var id = UUID()
    var isLike = false
    var tictoker = "Leo"
}
struct VideoItem:Identifiable,Hashable{
    var id = UUID()
    var youtuber = "calmdownman"
}
final class TempVC: UIViewController{
    enum MediaType{
        case video
        case music
        case shortVideo
    }
    // 비디오 구조체만 콜렉션 뷰에 보여줄꺼니..?
    var dataSource: UICollectionViewDiffableDataSource<MediaType,VideoItem>!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

그러나 이 사용법으로는 Compositional Layout에서 지원하는 하나의 컬렉션 뷰에 다양한 섹션과 각각의 섹션마다 다른 셀 아이템을 보여주는 코드를 작성할 수 없다..!

예컨데, 앱스토어 이미지에서 Discover Section의 Cell과 Suggested Section의 Cell에서 요구되는 데이터는 다르다.

이를 해결하기 위해 Identifiable 프로토콜의 ID를 이용한다.

응용 UICollectionViewDiffableDataSource

데이터 소스 타입은 다음과 같다.

...
var dataSource: UICollectionViewDiffableDataSource<MediaType,Item>!
...

MediaType과 Identifiable.ID

이 인스턴스가 고유한 (식별 가능한) 값을 갖는다는 의미이다. → 주민등록번호와 같음…

 

 

Identifiable | Apple Developer Documentation

A class of types whose instances hold the value of an entity with stable identity.

developer.apple.com

enum MediaType{
        case video
        case music
        case shortVideo
    }
  • Enum 타입 또한 id에 적용할 수 있다. ⇒ Case들이 고유성을 갖으니깐

DiffableDataSource용 Item Struct

  • 이 구조체는 CollectionView에 데이터들을 표현하기 위해 만들어낸다.
  • 두 가지 변수를 갖는다.
    1. VideoItem, ShortVideo, MusicItem와 같이 데이터 구조체들의 고유 id 값
    2. 각각의 Section과 데이터들간의 정보를 일치하기 위한 Enum 값
    3. struct Item:Identifiable,Hashable{ var id:UUID var itemType: MediaType }

전체 구조 코드

struct MusicItem:Identifiable,Hashable{
    var id = UUID()
    var artist = "Newjeans"
}
struct ShortVideo:Identifiable,Hashable{
    var id = UUID()
    var isLike = false
    var tictoker = "Leo"
}

struct VideoItem:Identifiable,Hashable{
    var id = UUID()
    var youtuber = "calmdownman"
}
final class TempVC: UIViewController{
    enum MediaType{
        case video
        case music
        case shortVideo
    }
    struct Item:Identifiable,Hashable{
        var id:UUID
        var itemType: MediaType
    }
    var videoItems = (0...20).map{_ in VideoItem()}
    var shortVideoItems = (0...40).map{_ in ShortVideo()}
    var musicItems = (0...60).map{_ in MusicItem()}
    var dataSource: UICollectionViewDiffableDataSource<MediaType,Item>!
    override func viewDidLoad() {
        super.viewDidLoad()
        var snapshot = NSDiffableDataSourceSnapshot<MediaType,Item>()
        snapshot.appendSections([.video,.music,.shortVideo])
        snapshot.appendItems(videoItems.map{Item(id: $0.id, itemType: .video)},toSection: .video)
        snapshot.appendItems(musicItems.map{Item(id: $0.id, itemType: .music)},toSection: .music)
        snapshot.appendItems(shortVideoItems.map{Item(id: $0.id, itemType: .music)},toSection: .shortVideo)
        dataSource.apply(snapshot,animatingDifferences: true)
    }
}

 

댓글