본문 바로가기

Mobile/iOS

[iOS] CollectionView - 댓글창 만들기(3)

반응형

이번 3편에서는 DataSource를 설정해보도록 하겠습니다.


1. extension ViewController

해당 코드는 ViewController의 viewDidLoad()에서 실행시켜 줄 예정입니다.

extension ViewController {
    fileprivate func configureDataSource() {
        // 여기에 DataSource 설정이 들어갑니다.
    }
}

2. Cell 등록

TableView에서도 Cell을 등록해주어야 하잖아요? 마찬가지입니다. CollectionView에서도 Cell을 아래와 같이 등록해줍니다. 조금 다른 부분은 CellRegistration<CommentViewCell, Int>로 등록을 해주는 것인데, 여기서 Int는 Item의 Identifier 입니다. 이것은 그때그때 필요에 맞게 변경해줄 수 있습니다.

cell을 등록할 때, cell에 들어갈 내용을 설정해줄 수 있습니다.

let cellRegistration = UICollectionView.CellRegistration<CommentCollectionViewCell, Int> {
    (cell, indexPath, identifier) in
    cell.nickName.text = "\(indexPath.item)"
    cell.comment.text = "안녕하세요 안녕하세요 "
}

3. DataSource 설정

DataSource설정 부분입니다. 아래와 같이 설정해주시면 됩니다. 마찬가지로 UICollectionViewDiffableDataSource<Int, Int>의 Int는 각각 Section, Item의 Identifier입니다.

dataSource = UICollectionViewDiffableDataSource<Int, Int>(
    collectionView: commentCollectionView
) {(
    collectionView: UICollectionView,
    indexPath: IndexPath,
    identifier: Int
) -> UICollectionViewCell? in
    return collectionView.dequeueConfiguredReusableCell(
        using: cellRegistration,
        for: indexPath,
        item: identifier)}

4. Header & Footer 등록

header와 footer를 등록해줍니다. CollectionView에 Cell로 들어가는 것이 아니라 SupplementaryView로 들어가는 것이기 때문에 Cell을 등록할 때와는 비슷하지만 다른 형태로 넣습니다.

let headerRegistration = UICollectionView
    .SupplementaryRegistration<CommentSupplementaryHeaderView>(elementKind: "header") {
        (supplementaryView, string, indexPath) in
        supplementaryView.nickName.text = "\(indexPath.section)"
        supplementaryView.comment.text = "안녕하세요 안녕하세요 안녕하세요 "
    }

let footerRegistration = UICollectionView
    .SupplementaryRegistration<CommentSupplementaryFooterView>(elementKind: "footer") {
        (supplementaryView, string, indexPath) in
    }

아래는 들어오는 dataSource의 종류에 따라 Header와 Footer를 구분해서 등록하는 과정입니다.

// header, footer 등록
dataSource.supplementaryViewProvider = {(view, kind, index) in
    if kind == "header" {
        return self.commentCollectionView
            .dequeueConfiguredReusableSupplementary(using: headerRegistration,
                                                    for: index)
    } else {
        return self.commentCollectionView
            .dequeueConfiguredReusableSupplementary(using: footerRegistration,
                                                    for: index)
    }
}

5. Snapshot

DiffableDataSource는 Snapshot을 이용해 데이터를 등록합니다. Snapshot에 관한 부분은 추후에 더 자세히 다뤄보도록 하겠습니다.

var snapshot = NSDiffableDataSourceSnapshot<Int, Int>()
var identifierOffset = 0
let itemPerSection = 3

for idx in 0...10 {
    snapshot.appendSections([idx])

    let maxIdentifier = identifierOffset + itemPerSection
    snapshot.appendItems(Array(identifierOffset..<maxIdentifier))
    identifierOffset += itemPerSection
}

dataSource.apply(snapshot)

snapshot의 형태는 DataSource와 동일한 타입입니다. 지금 저희는 따로 데이터가 없는 상태이기 때문에 For문으로 숫자를 불러와 Index로 사용해 Item의 수, Section의 수를 설정하겠습니다.

identifierOffset은 아이템의 순서를 얘기합니다. 예를들어 0번부터 100번까지의 데이터가 있다고 하면 Item에 0번부터 100번까지 하나씩 Identifier를 설정해주는 부분입니다.

itemPerSection은 하나의 섹션에 몇 개의 아이템이 들어가는지 설정하는 부분입니다.

cell.nickname 부분을 실행해보시면 더욱 이해하시기 편할겁니다.

// cell.nickName.text = "\(indexPath.item)"
cell.nickName.text = "\(identifier)"

여기까지 하면 아래와 같은 결과물을 얻으실 수 있습니다.


전체 코드를 보고 싶으시면 "더보기"를 눌러주세요.
궁금하신 내용이 있으시면 답글 달아주세요 !

더보기
extension ViewController {
    fileprivate func configureDataSource() {

        let cellRegistration = UICollectionView.CellRegistration<CommentCollectionViewCell, Int> {
            (cell, indexPath, identifier) in
            cell.nickName.text = "\(indexPath.item)"
            cell.comment.text = "안녕하세요 안녕하세요 "
        }

        dataSource = UICollectionViewDiffableDataSource<Int, Int>(
            collectionView: commentCollectionView
        ) {(
            collectionView: UICollectionView,
            indexPath: IndexPath,
            identifier: Int
        ) -> UICollectionViewCell? in
            return collectionView.dequeueConfiguredReusableCell(
                using: cellRegistration,
                for: indexPath,
                item: identifier)}

        let headerRegistration = UICollectionView
            .SupplementaryRegistration<CommentSupplementaryHeaderView>(elementKind: "header") {
                (supplementaryView, string, indexPath) in
                supplementaryView.nickName.text = "\(indexPath.section)"
                supplementaryView.comment.text = "안녕하세요 안녕하세요 안녕하세요 "
            }

        let footerRegistration = UICollectionView
            .SupplementaryRegistration<CommentSupplementaryFooterView>(elementKind: "footer") {
                (supplementaryView, string, indexPath) in
            }

        // header, footer 등록
        dataSource.supplementaryViewProvider = {(view, kind, index) in
            if kind == "header" {
                return self.commentCollectionView
                    .dequeueConfiguredReusableSupplementary(using: headerRegistration,
                                                            for: index)
            } else {
                return self.commentCollectionView
                    .dequeueConfiguredReusableSupplementary(using: footerRegistration,
                                                            for: index)
            }
        }
        
        var snapshot = NSDiffableDataSourceSnapshot<Int, Int>()
        var identifierOffset = 0
        let itemPerSection = 3
        
        for idx in 0...10 {
            snapshot.appendSections([idx])
            
            let maxIdentifier = identifierOffset + itemPerSection
            snapshot.appendItems(Array(identifierOffset..<maxIdentifier))
            identifierOffset += itemPerSection
        }
        
        dataSource.apply(snapshot)
    }
}

 

반응형