[Swift] Code Base로 CollectionView 구현하기

장일규·2022년 1월 8일


Custom Layout을 구현 시 UICollectionViewLayout을 서브클래싱 한다.

1. 즉시실행 함수 클로저 만들기

UICollectionView타입에 즉시 실행 함수 클로저를 만듭니다.

    let collectionView:  UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .systemPink
        return cv
    }()

2. delegate 설정

    func configureCollectionView() {
        collectionView.register(MainCell.self, forCellWithReuseIdentifier: mainCellId)
        // 컬렉션 뷰의 기능을 누가 사용하지는지 ? 👉 self 즉, 나 자신 클래스인 MainViewController
        collectionView.delegate = self
        //  컬렉션 뷰의 데이타 제공자는 ? 👉  self 즉, 나 자신 클래스인 MainViewController
        collectionView.dataSource = self
    }

delegate까지 설정하면 아래와 같은 에러가 발생합니다.

Cannot assign value of type 'MainViewController' to type 'UICollectionViewDelegate?'
Add missing conformance to 'UICollectionViewDelegate' to class 'MainViewController'
Add missing conformance to 'UICollectionViewDataSource' to class 'MainViewController'

MainViewController클래스에 UICollectionViewDelegateUICollectionViewDataSource프로토콜을 채택해주어야 합니다.

  extension MainViewController: UICollectionViewDelegate,UICollectionViewDataSource {

  }

⛔️그럼 또 에러가 발생합니다.

Type 'MainViewController' does not conform to protocol 'UICollectionViewDataSource'

UICollectionViewDataSource를 채택하면 아래와 같이 2개의 메소드를 필수로 선언해야합니다.

cell에 관한 delegate

  • 아이템의 개수 : collectionView(_:numberOfItemsInSection:)

  • 셀 생성 : collectionView(_:cellForItemAt:)

  extension MainViewController: 
      UICollectionViewDelegate,
      UICollectionViewDataSource,
      UICollectionViewDelegateFlowLayout{
      
      // 컬렉션 뷰의 아이템이 몇개인지???
      func collectionView(
          _ collectionView: UICollectionView,
          numberOfItemsInSection section: Int
      ) -> Int {
          return 7
      }
      
     // 컬렉션 뷰의 하나의 단위를 cell이라고 함
     // 어떤 모양의 cell인지
     func collectionView(
          _ collectionView: UICollectionView,
          cellForItemAt indexPath: IndexPath
     ) -> UICollectionViewCell {
            guard let cell = collectionView.dequeueReusableCell(
            withReuseIdentifier: mainCellId ,
            for: indexPath) as? MainCell else {
                return UICollectionViewCell()
            }
     }
      
     // 컬렉션 뷰의  샤이즈
     func collectionView(
          _ collectionView: UICollectionView,
          layout collectionViewLayout: UICollectionViewLayout,
          sizeForItemAt indexPath: IndexPath
     ) -> CGSize {
          return CGSize(width: 300, height: 100)
     }
  }

Cell의 layout에 대한 delegate

필수 프로토콜 채택 외에 UICollectionViewDelegateFlowLayout를 채택하여 셀 예상 크기를 지정하였습니다.

  • 위 아래 간격 : collectionView(_:layout:minumumLineSpacingForSectionAt:)

  • 옆 간격 : collectionView(_:layout:minimumInteritemSpacingForSectionAt:)

  • cell사이즈 : collectionView(_:layout:sizeForItemAt:)

// cell layout
extension ViewController: UICollectionViewDelegateFlowLayout {

    // 위 아래 간격
    func collectionView(
    	_ collectionView: UICollectionView, 
        layout collectionViewLayout: UICollectionViewLayout, 
        minimumLineSpacingForSectionAt section: Int
        ) -> CGFloat {
        return 5
    }

    // 옆 간격
    func collectionView(
      _ collectionView: UICollectionView, 
      layout collectionViewLayout: UICollectionViewLayout, 
      minimumInteritemSpacingForSectionAt section: Int
      ) -> CGFloat {
          return 3
      }

    // cell 사이즈( 옆 라인을 고려하여 설정 )
    func collectionView(
      _ collectionView: UICollectionView, 
      layout collectionViewLayout: UICollectionViewLayout, 
      sizeForItemAt indexPath: IndexPath
      ) -> CGSize {
      
        return size
    }
}

Reuse Mechanism

Collection View는 재사용 메커니즘을 사용한다.

Cell Prefetching

Collection View는 성능을 높이기 위해 2가지 prefetching 기술을 제공한다.

Cell Prefetching
Data Prefetching

화면에 나타날 Cell을 미리 준비한 후 스크롤 시 발생하는 끊김 현상을 방지 한다.

기본적으로 활성화 되어있고, 자동으로 처리됨

0개의 댓글