[swift] Swift IGListKit에서 컬렉션 뷰 다중 선택 처리하기

IGListKit은 iOS 애플리케이션에서 컬렉션 뷰 구현을 도와주는 강력한 프레임워크입니다. 이 프레임워크를 사용하면 데이터 소스와 컬렉션 뷰를 쉽게 연동하여 다양한 UI를 구현할 수 있습니다. 하지만 IGListKit은 컬렉션 뷰의 다중 선택을 기본적으로 제공하지 않습니다. 이번 글에서는 IGListKit을 사용하여 컬렉션 뷰에서 다중 선택을 처리하는 방법을 알아보겠습니다.

다중 선택을 위한 모델 구현

먼저, 다중 선택을 위한 모델을 작성해야 합니다. IGListKit에서는 각 셀이 선택되었는지 여부를 표시하는 isSelected 속성을 가진 모델을 사용합니다.

class Item: NSObject, ListDiffable {
    let identifier: String
    var isSelected: Bool
    
    init(identifier: String, isSelected: Bool) {
        self.identifier = identifier
        self.isSelected = isSelected
    }
    
    // IGListKit에서 필요한 메서드 구현
    func diffIdentifier() -> NSObjectProtocol {
        return identifier as NSObjectProtocol
    }
    
    func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
        guard let object = object as? Item else { return false }
        return identifier == object.identifier && isSelected == object.isSelected
    }
}

위의 코드는 Item 클래스를 정의하고, IGListKit에서 필요한 diffIdentifier()isEqual(toDiffableObject:) 메서드를 구현한 것입니다. 이 클래스는 identifierisSelected 속성을 가지며, 컬렉션 뷰에서 선택된 상태를 표시하기 위해 isSelected를 사용합니다.

데이터 소스 구현

이제 데이터 소스를 구현합니다. IGListKit의 데이터 소스는 ListBindingSectionController 를 상속받는 클래스로 구현됩니다. ListBindingSectionController 는 컬렉션 뷰의 섹션을 관리하고 셀을 제어하는 역할을 합니다.

class MultipleSelectionSectionController: ListBindingSectionController<Item> {
    override init() {
        super.init()
        selectionDelegate = self
    }
    
    override func cellForItem(at index: Int) -> UICollectionViewCell {
        // 셀 생성 및 설정
    }
    
    override func sizeForItem(at index: Int) -> CGSize {
        // 셀 크기 반환
    }
}

extension MultipleSelectionSectionController: ListBindingSectionControllerSelectionDelegate {
    func sectionController(_ sectionController: ListBindingSectionController<ListDiffable>, didSelectItemAt index: Int, viewModel: Any) {
        guard let item = viewModel as? Item else { return }
        item.isSelected = !item.isSelected
        update(animated: true)
    }
}

위의 코드에서 MultipleSelectionSectionController 클래스는 ListBindingSectionController 클래스를 상속받고, ListBindingSectionControllerSelectionDelegate 프로토콜을 구현합니다. selectionDelegate를 설정하여 셀의 선택 이벤트를 처리할 수 있습니다.

cellForItem(at index: Int) 메서드에서는 셀을 생성하고 설정합니다. sizeForItem(at index: Int) 메서드에서는 셀의 크기를 반환합니다.

sectionController(_:didSelectItemAt:viewModel:) 메서드에서는 셀이 선택되었을 때의 동작을 정의합니다. 선택된 셀의 isSelected 속성을 변경하고, update(animated: true) 메서드를 호출하여 변경된 상태를 업데이트합니다.

컬렉션 뷰 컨트롤러에서 사용하기

마지막으로, 컬렉션 뷰 컨트롤러에서 MultipleSelectionSectionController 를 사용하도록 설정해야 합니다.

class ViewController: UIViewController {
    let collectionView: UICollectionView = {
        // 컬렉션 뷰 생성 및 설정
    }()
    
    let adapter: ListAdapter = {
        // ListAdapter 객체 생성 및 설정
    }()
    
    var data: [Item] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 데이터 초기화
        data = [
            Item(identifier: "1", isSelected: false),
            Item(identifier: "2", isSelected: false),
            Item(identifier: "3", isSelected: false)
        ]
        
        // 데이터 소스 설정
        adapter.collectionView = collectionView
        adapter.dataSource = self
    }
}

extension ViewController: ListAdapterDataSource {
    func objects(for listAdapter: ListAdapter) -> [ListDiffable] {
        return data
    }
    
    func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController {
        return MultipleSelectionSectionController()
    }
    
    func emptyView(for listAdapter: ListAdapter) -> UIView? {
        return nil
    }
}

위의 코드는 ViewController에서 IGListKit의 ListAdapter를 사용하고, Adapter의 데이터 소스로 ViewController의 셀 객체를 생성하는 방법을 보여줍니다. 데이터 초기화 후 adapter.dataSource 에 데이터 소스를 지정하고, listAdapter(_:sectionControllerFor:) 메서드에서 MultipleSelectionSectionController를 반환하도록 설정합니다.

이제 IGListKit을 사용하여 컬렉션 뷰에서 다중 선택을 처리할 수 있습니다.

결론

이번 글에서는 IGListKit을 사용하여 컬렉션 뷰에서 다중 선택을 처리하는 방법을 알아보았습니다. IGListKit의 강력한 기능과 뛰어난 확장성을 활용하여 다양한 컬렉션 뷰 UI를 구현할 수 있습니다. 추가적인 기능을 구현하려면 IGListKit의 공식 문서를 참고하시기 바랍니다.

참고 자료