본문 바로가기
UIKit

코드베이스로 UICollectionView 구현하기

by 리버🐦‍🔥 2023. 10. 10.
<UICollectionView>
  • 컬렉션 뷰를 생성하고 표시하는 데 사용
  • 그리드 형태의 데이터를 표시하고 편집하는 데 사용
[Method & Property]
  • register(): UICollectionView에서 사용할 셀 클래스를 등록하는 역할. 어떤 종류의 셀을 표시할 것인지 알려주는 역할
  • dataSource: 데이터 소스를 테이블 뷰에 할당하여 테이블 뷰가 데이터를 어디서 가져와서 어떻게 표시할 지를 알려주기 위해 설정 (UICollectionView가 속한 컨트롤러에 "UICollectionViewDataSource" 프로토콜을 추가해야 한다. 해당 프로토콜을 따르기 위해서는 collectionView()라는 메서드가 필요하다.)
  • delegate: 테이블 뷰의 동작 및 사용자 상호 작용(셀 선택, 스크롤 등…)을 제어하기 위해 사용. (UICollectionView가 속한 컨트롤러에 "UICollectionViewDelegateFlowLayout" 프로토콜을 추가해야 한다.)
<UICollectionViewFlowLayout>
  • 그리드 형태의 레이아웃을 쉽게 구현할 수 있도록 도와주는 클래스
  • 셀의 크기, 간격, 그룹화 등을 쉽게 설정할 수 있다.
[Method & Property]
  • .scrollDirection: 그리드가 수직적인지 수평적인지 지정할 수 있는 프로퍼티
등… 프로퍼티 및 메서드 추가로 공부해보기!
//
//  UICollectionViewTest.swift
//  UIKit-Study
//
//  Created by Kyungsoo Lee on 2023/09/30.
//

import UIKit

class UICollectionViewTest: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    // MARK: - UICollectionView
    private lazy var uiCollectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        // frame을 .zero로 사용하여 CGRect(0, 0, 0, 0)으로 초기화하고, 이후 오토 레이아웃을 통해 layout을 설정한다.
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.backgroundColor = .white
        // UICollectionView가 속한 컨트롤러에 "UICollectionViewDataSource" 프로토콜을 추가해야 한다.
        // "UICollectionViewDataSource" 프로토콜을 따르기 위해선 collectionView()를 반드시 선언해야 한다.
        collectionView.dataSource = self
        // UICollectionView가 속한 컨트롤러에 "UICollectionViewDelegateFlowLayout" 프로토콜을 추가해야 한다.
        collectionView.delegate = self
        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        
        return collectionView
    }()
    
    
    // MARK: - UICollectionViewDataSource 메서드
    // 특정 섹션에 속하는 아이템(셀)의 총 개수를 반환한다.
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    // 각 셀을 생성하고 구성하기 위해 호출
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        // dequeueReusableCell()을 통해 재사용 가능한 셀을 얻는다. 셀이 없으면 재사용 큐에 셀을 생성한다.
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        cell.backgroundColor = .red
        return cell
    }
    
    // MARK: - UICollectionViewDelegateFlowLayout
    
    // CollectionView에 들어갈 Item에 size에 대한 정보
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 50, height: 50)
    }
    
    // CollectionView에 들어갈 셀 사이의 minimum spacing에 대한 정보
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 10
    }
    
    // CollectionView에 들어갈 각 Item의 Inset(여백) 대한 정보
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    }
    
    // MARK: - viewDidLoad
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        self.view.backgroundColor = .systemGray
        
        // 뷰 추가(아직 layout 설정 안된 상태)
        self.view.addSubview(self.uiCollectionView)
        
        setLayout()
    }
    
    // MARK: - UICollectionView 제약 조건
    private func setUICollectionViewLayout() {
        let uiCollectionViewConstraint = [
            uiCollectionView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            uiCollectionView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            uiCollectionView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8),
            uiCollectionView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.6)
        ]
        NSLayoutConstraint.activate(uiCollectionViewConstraint)
        
    }
    
    // MARK: - 전체 제약조건 설정
    // 컴포넌트들의 레이아웃을 설정한다
    private func setLayout() {
        // 프레임 기반의 레이아웃을 비활성화 하여 오토 레이아웃을 기반으로 설정할 수 있도록 한다.
        
        // UICollectionView 제약조건 설정
        setUICollectionViewLayout()
    }
}

// UIKit으로 짠 화면을 SwiftUI로 바로 볼 수 있게 해주는 코드
import SwiftUI

@available(iOS 13.0.0, *)
struct UICollectionViewTestControllerPreview: PreviewProvider {
    static var previews: some View {
        UICollectionViewTest().toPreview()
    }
}