결과물

사용 라이브러리 - SnapKit , Then

구현 코드 - https://github.com/ryr0121/UIKitPractice/tree/main/DoubleCVPractice

 

포함 관계

노란색 배경 CollectionView > 파란색 배경 CollectionView > 초록색 배경 View (Cell)

 

구현 과정

1. ViewController안에 노란색 배경의 CollectionView 정의

class ViewController: UIViewController {
	...
	var collectionView: UICollectionView!

	func setupCollectionView() {
        collectionView = UICollectionView(frame: .zero, collectionViewLayout: .init()).then{
            let flowLayout = UICollectionViewFlowLayout()
            flowLayout.itemSize = CGSize(width: self.view.frame.width, height: 100)
            flowLayout.scrollDirection = .vertical
            flowLayout.minimumLineSpacing = 10

            $0.collectionViewLayout = flowLayout
            $0.delegate = self
            $0.dataSource = self
            $0.backgroundColor = .yellow

            $0.showsHorizontalScrollIndicator = false

            $0.decelerationRate = .fast
            $0.isPagingEnabled = false

            $0.register(MainCollectionViewCell.self, forCellWithReuseIdentifier: MainCollectionViewCell.identifier)
        }
	}
	...
}

 

2. ViewController 내에서 CollectionView 관련 프로토콜을 채택하며 cellForItemAt 메소드 내에 새롭게 정의한 CollectionViewCell을 반환시킴

extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MainCollectionViewCell.identifier, for: indexPath) as? MainCollectionViewCell else { return UICollectionViewCell() }
        return cell
    }
}

 

3. 위에서 반환되는 셀(파란색 배경)을 정의하는 CollectionViewCell 클래스 내에서 해당 클래스에 또 다른 CollectionView를 가지도록 정의 및 프로토콜 채택

class MainCollectionViewCell: UICollectionViewCell {
    ...    
    var subCollectionView: UICollectionView!

    func setupCollectionView() {
        subCollectionView = UICollectionView(frame: .zero, collectionViewLayout: .init()).then{
            let flowLayout = UICollectionViewFlowLayout()
            flowLayout.itemSize = CGSize(width: 100, height: 100)
            flowLayout.scrollDirection = .horizontal
            flowLayout.minimumLineSpacing = 10

            $0.collectionViewLayout = flowLayout
            $0.delegate = self
            $0.dataSource = self
            $0.backgroundColor = .systemBlue

            $0.showsHorizontalScrollIndicator = false

            $0.decelerationRate = .fast
            $0.isPagingEnabled = false

            $0.register(SubCollectionViewCell.self, forCellWithReuseIdentifier: SubCollectionViewCell.identifier)
        }
    }
    ...
}

extension MainCollectionViewCell: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SubCollectionViewCell.identifier, for: indexPath) as? SubCollectionViewCell else { return UICollectionViewCell() }
        return cell
    }
}

 

4. 파란색 배경의 셀이 가지는 CollectionView의 셀을 정의하는 클래스(초록색 아이템)를 정의

class SubCollectionViewCell: UICollectionViewCell {
    static let identifier = "SubCollectionViewCell"

    var containerView = UIView().then { $0.backgroundColor = .green }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.contentView.addSubview(containerView)
        
        containerView.snp.makeConstraints { make in
            make.top.leading.bottom.trailing.equalToSuperview().inset(5)
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

 

+ Recent posts