Swift/UIKit

[UIKit] UICollectionViewDiffableDataSource에 대해 알아보자

insub4067 2022. 11. 27. 18:38

 

What is 

iOS 13 부터 지원되는 CollectionView 와 TableView 에서 정보를 화면에 뿌려주는 방법중하나이다.

보통 datasource delegate method 를 통해 화면에 뿌려주곤한다. 하지만 델리게이트를 사용하지 않고도 UICollectionViewDiffableDataSource 를 사용하면 보자 자연스럽게 애니메이션을 더해서 화면에 정보를 뿌려줄수 있다.

 

Why

delegate method 를 통해 구현된 화면은 보여줘야할 정보가 변경될때 

예를 들면 검색창을 통해 입력이 들어와 필터링 해줘야한다면 화면이 바뀌어야하는데

기존에는 reloadData() 를 통해 화면을 새로 그려주었는데 그렇게 되면 화면이

애니메이션없이 뚝뚝 끊기게 된다면 그렇기 때문에 좋지 못한 UX 라고 할수 있었다

 

 

위 화면은 diffable 로 구현된 화면이다

보여줘야할 출력값이 바뀌더라도 자연스럽게 애니메이션을 통해 화면이 바뀐다.

보여줘야할 array는 Hashable을 상속받고 있어야 한다.

struct Follower: Codable, Hashable {
    var login: String
    var avatarUrl: String
}

enum Section { case main }

var followers: [Follower] = []
var filteredFollowers: [Follower] = []
var dataSource: UICollectionViewDiffableDataSource<Section, Follower>!
var collectionView: UICollectionView!
var dataSource: UICollectionViewDiffableDataSource<Section, Follower>!

func configureDataSource() {
    dataSource = UICollectionViewDiffableDataSource<Section, Follower>(
        collectionView: collectionView,
        cellProvider: { collectionView, indexPath, follower in
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FollowerCell.reuseID, for: indexPath) as! FollowerCell
        cell.set(follower: follower)
        return cell
    })
}

func updateData(on followers: [Follower]) {
    var snapshot = NSDiffableDataSourceSnapshot<Section, Follower>()
    snapshot.appendSections([.main])
    snapshot.appendItems(followers)
    DispatchQueue.main.async { [weak self] in
        guard let self = self else { return }
        self.dataSource.apply(snapshot, animatingDifferences: true)
    }
}

func updateSearchResults(for searchController: UISearchController) {
    guard let filter = searchController.searchBar.text,
          !filter.isEmpty else
    {
        filteredFollowers.removeAll()
        isSearching = false
        updateData(on: followers)
        return
    }
    isSearching = true
    filteredFollowers = followers.filter { $0.login.lowercased().contains(filter.lowercased()) }
    updateData(on: filteredFollowers)
}

 

 

 

UI Diffable Data Source란?

추가적인 코드작업 없이도, 퀄리티 있는 에니메이션 적용이 가능하다. 개선된 Data Source 매커니즘은 완벽하게 동기적인 버그나, 예외, 충돌 상황들을 피할 수 있게 해준다. UI 데이터의 동기화 부

velog.io

 

Apple Developer Documentation

 

developer.apple.com