[swift] Swift IGListKit에서 컬렉션 뷰 다중 선택 기능 구현하기

IGListKit은 iOS 앱에서 컬렉션 뷰를 구성하는 데 도움이 되는 강력한 프레임워크입니다. IGListKit을 사용하여 컬렉션 뷰를 다중 선택할 수 있는 기능을 구현하는 방법을 살펴보겠습니다.

IGListKit 설치하기

먼저, 프로젝트에 IGListKit을 설치해야 합니다. 이를 위해 CocoaPods를 사용할 수 있습니다. Podfile에 다음과 같이 IGListKit을 추가합니다.

pod 'IGListKit'

그리고 터미널에서 pod install을 실행하여 IGListKit을 프로젝트에 설치합니다.

IGListKit 컬렉션 뷰 구성하기

IGListKit의 기본적인 사용법은 복잡하지 않으며, 아래와 같은 단계로 컬렉션 뷰를 구성할 수 있습니다.

  1. IGListKit의 ListCollectionView 클래스를 사용하여 컬렉션 뷰를 생성합니다.
  2. 컬렉션 뷰에 사용할 데이터 모델과 셀과 관련된 클래스를 작성합니다.
  3. IGListKit의 ListAdapter 클래스를 사용하여 컬렉션 뷰와 데이터 모델을 연결합니다.

다중 선택 기능을 구현하기 위해 데이터 모델에 선택 상태를 저장하는 속성을 추가합니다. 예를 들어, 다음과 같은 Item 클래스를 작성할 수 있습니다.

class Item: NSObject {
    let id: Int
    var isSelected: Bool
    
    init(id: Int, isSelected: Bool = false) {
        self.id = id
        self.isSelected = isSelected
    }
}

컬렉션 뷰 셀 구성하기

선택 가능한 컬렉션 뷰 셀을 작성하기 위해 IGListKit의 ListBindable 프로토콜을 채택합니다. 이 프로토콜을 채택하는 클래스는 bindViewModel(_:Any) 메서드를 구현해야 합니다. 선택 상태에 따라 셀의 외관을 변경하기 위해 해당 로직을 구현합니다.

class ItemCell: UICollectionViewCell, ListBindable {
    var item: Item?
    
    // 셀의 외관을 업데이트하는 로직을 구현합니다
    func bindViewModel(_ viewModel: Any) {
        guard let item = viewModel as? Item else { return }
        self.item = item
        
        if item.isSelected {
            self.backgroundColor = UIColor.blue
        } else {
            self.backgroundColor = UIColor.white
        }
    }
}

다중 선택 기능 구현하기

다중 선택 기능을 구현하기 위해 IGListKit의 ListBindingSectionController를 사용합니다. 이를 위해서는 ListBindingSectionController 클래스를 상속받는 새로운 클래스를 작성해야 합니다. 다음은 MultipleSelectionSectionController 클래스의 예입니다.

class MultipleSelectionSectionController: ListBindingSectionController<Item> {
    override func cellForItem(at index: Int) -> UICollectionViewCell {
        guard let cell = collectionContext?.dequeueReusableCell(of: ItemCell.self, for: self, at: index) as? ItemCell else { fatalError() }
        return cell
    }
    
    override func didUpdate(to object: Any) {
        guard let item = object as? Item else { fatalError() }
        if let cell = (collectionContext?.cellForItem(at: section) as? ItemCell) {
            cell.item = item
        }
    }
    
    override func didSelectItem(at index: Int) {
        super.didSelectItem(at: index)
        
        guard let item = object(at: index) else { return }
        item.isSelected.toggle()
        
        if let cell = (collectionContext?.cellForItem(at: index, sectionController: self) as? ItemCell) {
            cell.bindViewModel(item)
        }
    }
}

컬렉션 뷰와 데이터 모델 연결하기

마지막으로, 컬렉션 뷰와 데이터 모델을 IGListKit의 ListAdapter 클래스를 사용하여 연결합니다. 이를 위해서는 IGListAdapterDelegate 프로토콜을 채택하고, ListBindingSectionController 클래스의 인스턴스를 생성하여 IGListAdapterDataSource 프로토콜을 구현해야 합니다.

class ViewController: UIViewController, IGListAdapterDelegate, IGListAdapterDataSource {
    // 컬렉션 뷰 인스턴스를 생성합니다.
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
    
    // 컬렉션 뷰와 데이터를 관리하는 ListAdapter 인스턴스를 생성합니다.
    lazy var adapter: ListAdapter = {
        return ListAdapter(updater: ListAdapterUpdater(), viewController: self, workingRangeSize: 0)
    }()
    
    // 컬렉션 뷰에 표시할 데이터 모델
    var items: [Item] = [
        Item(id: 1),
        Item(id: 2),
        Item(id: 3)
    ]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 컬렉션 뷰를 설정합니다.
        self.view.addSubview(collectionView)
        collectionView.backgroundColor = .white
        collectionView.frame = self.view.bounds
        
        // ListAdapter의 delegate와 dataSource를 설정합니다.
        adapter.collectionView = collectionView
        adapter.delegate = self
        adapter.dataSource = self
    }
    
    // MARK: - IGListAdapterDelegate
    
    func listAdapter(_ listAdapter: ListAdapter, willDisplay sectionController: ListSectionController, cell: UICollectionViewCell, at index: Int) {
        // 셀이 표시될 때 호출되는 메서드입니다.
    }
    
    func listAdapter(_ listAdapter: ListAdapter, didEndDisplaying sectionController: ListSectionController, cell: UICollectionViewCell, at index: Int) {
        // 셀이 표시를 종료할 때 호출되는 메서드입니다.
    }
    
    // MARK: - IGListAdapterDataSource
    
    func objects(for listAdapter: ListAdapter) -> [ListDiffable] {
        return items
    }
    
    func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController {
        return MultipleSelectionSectionController()
    }
    
    func emptyView(for listAdapter: ListAdapter) -> UIView? {
        return nil // 필요에 따라 빈 화면을 표시할 수 있습니다.
    }
}

위의 코드를 실행하면 컬렉션 뷰가 표시되고, 사용자가 셀을 선택하면 다중 선택이 가능하게 됩니다.

이제 IGListKit을 사용하여 Swift로 컬렉션 뷰 다중 선택 기능을 구현하는 방법을 알게 되었습니다. IGListKit의 다른 기능 및 세부 정보에 대해서는 공식 문서를 확인해보세요.