본문 바로가기

iOS 앱 개발자 프로젝트

[iOS] UICollectionViewCell 안에 UICollectionView 넣기

앞의 글에서 화면 전체(SafeArea)를 콜렉션뷰로 설정하고 섹션을 세개로 나누었어요.

 

이제, 나눠진 섹션에 들어가는 캐로셀의 코드를 작성하고, 화면(TodoCalandarViewController) 에 연결해 봅니다.


 

 

1. UICollectionViewDelegateFlowLayout 프로토콜을 채택 : 셀의 크기를 설정

class TodoCalandarViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

 

프로토콜을 채택하지 않으면 collectionView(_:layout:sizeForItemAt:) 메서드 사용할 없다.

 

 

 

2. collectionView(_:layout:sizeForItemAt:) 메서드를 구현 : 셀의 크기를 설정

// 셀 크기 설정
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 350, height: 244)
}

 

셀의 크기를 CGSize(width: 350, height: 244) 설정했다.

 

 

 

3. CollectionViewCell 대한 설정에서 번째 섹션의 testCollectionView 숨기지 않도록 설정

// 셀 구성
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as? CollectionViewCell else {
        return UICollectionViewCell()
    }
    
    // 첫 번째 섹션의 셀에 대한 설정
    if indexPath.section == 0 {
        cell.testCollectionView.isHidden = false
    } else {
        cell.testCollectionView.isHidden = true
    }
    
    return cell
}

 

 

 

+ CollectionViewCell 파일 추가 :  horizontal 스크롤이 가능한 캐로셀 컬렉션 (testCollectionView) 포함

 

  1. CollectionViewCell 클래스 UICollectionView 서브뷰로 포함하여 수평 스크롤이 가능한 캐로셀 뷰를 구현하고,
  2. testCollectionView YZCenterFlowLayout 사용하여 아이템을 캐로셀로 배치 (YZCenterFlowLayout 별도 추가)
  3. 델리게이트 데이터 소스 메서드 testCollectionView 아이템 개수, 구성, 크기 등을 설정
import UIKit
import SnapKit

class CollectionViewCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    
    // 상단 캐로셀 컬렉션 뷰 설정
    var testCollectionView: UICollectionView = {
        let layout = YZCenterFlowLayout()
        
        // 캐로셀 방향 설정
        layout.scrollDirection = .horizontal
        
        // 애니매이션 모드 설정
        layout.animationMode = YZCenterFlowLayoutAnimation.scale(sideItemScale: 0.6, sideItemAlpha: 0.6, sideItemShift: 0.0)
        
        // 셀 간격 설정
        layout.spacingMode = .fixed(spacing: 10)
        
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.backgroundColor = .systemBackground
        collectionView.register(CarouselCell.self, forCellWithReuseIdentifier: "CarouselCell")
        
        return collectionView
    }()
    
    // 초기화 메서드
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        // 뷰의 배경색 (뒤에 있어서 안보임)
        backgroundColor = .blue
        
        // 테스트 컬렉션 뷰(파란색)를 현재 뷰의 서브뷰로 추가
        addSubview(testCollectionView)
        
        // 테스트 컬렉션 뷰의 제약 조건을 설정: 슈퍼 뷰(cyan 컬러)와 동일한 크기
        testCollectionView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        // 테스트 컬렉션 뷰의 델리게이트, 데이터소스를 현재 클래스로 설정
        testCollectionView.delegate = self
        testCollectionView.dataSource = self
        
        // 테스트 컬렉션 뷰의 배경색을 청록색(cyan)으로 설정
        testCollectionView.backgroundColor = .cyan
    }
    
    // 코드 기반 초기화 메서드
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // label의 text를 설정하고 testCollectionView의 데이터를 다시 로드
    func configure(with text: String) {
        // Label을 실제 셀에 추가
        addSubview(label)
        label.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        label.text = text
        testCollectionView.reloadData()
    }
    
    //레이블 설정
    private let label: UILabel = {
        let label = UILabel()
        label.textColor = .white // 텍스트 색상을 흰색으로 설정
        label.font = .systemFont(ofSize: 18, weight: .bold)
        return label
    }()
    
    // 콜렉션뷰에 10개의 셀을 선언
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10 // 아이템 개수
    }
    
    // 셀 구성
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CarouselCell", for: indexPath)
        
        // 셀에 대한 설정
        cell.backgroundColor = .blue
        
        return cell
    }
    
    // 셀 크기 설정
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 194, height: 244)
    }
}

// CarouselCell 클래스 정의 (필요에 따라 정의)
class CarouselCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupView() {
        // 내부 셀에 대한 추가 설정이 필요한 경우 여기에 작성
    }
}

 

첫번째 섹션에 UICollectionView(cyan color)를 넣고 CarouseCell(black color) 추가



상단 캐로셀 연결 성공

 

 

 

수정한 TodoCalandarViewController 전체

import UIKit
import SnapKit

class TodoCalandarViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    
    // 콜렉션뷰 선언 (지연 초기화 사용)
    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical  // 스크롤 방향을 수직으로 설정
        
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .yellow  // 콜렉션뷰 배경색을 노란색으로 설정
        return cv
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configureBackground()  // 배경 설정 메서드 호출
        configureFloatingButton()  // 플로팅 버튼 설정 메서드 호출
        setup()  // 콜렉션뷰 설정 메서드 호출
        
        // 셀 등록
        collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
        
        // 델리게이트 및 데이터 소스 설정
        collectionView.delegate = self
        collectionView.dataSource = self
    }
    
    // 콜렉션뷰 설정
    func setup() {
        view.addSubview(collectionView)  // 콜렉션뷰를 서브뷰로 추가
        
        // SnapKit을 사용하여 콜렉션뷰의 제약 조건 설정
        collectionView.snp.makeConstraints {
            $0.edges.equalTo(self.view.safeAreaLayoutGuide)  // 콜렉션뷰를 안전 영역에 맞춤
        }
    }
    
    // 콜렉션뷰에 3개의 섹션을 선언
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 3
    }
    
    // 각 섹션에 한 개의 셀 넣어주기
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 1
    }
    
    // 셀 구성
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as? CollectionViewCell else {
            return UICollectionViewCell()
        }
        
        // 첫 번째 섹션의 셀에 대한 설정
        if indexPath.section == 0 {
            cell.testCollectionView.isHidden = false
        } else {
            cell.testCollectionView.isHidden = true
        }
        
        return cell
    }
    
    // 셀 크기 설정
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 360, height: 244)
    }
}