맛동산이

Swift) 컬렉션뷰 (CollectionView) 레이아웃 -1 본문

앱/Swift

Swift) 컬렉션뷰 (CollectionView) 레이아웃 -1

진ddang 2024. 3. 2. 17:02

CollectionView

우선 컬렉션뷰가 어떻게 생겻는지 보고 가자.

Untitled.png

Untitled.png

컬렉션뷰는 다음과 같이 content-related object와, layout-realated data object로 이루어 진다.

content-related object

content relataed object는 테이블뷰와 동일하게 delegate, datasource로 이루어져 있다. 해당 메소드에서는 셀에 각각 어떠한 내용이 들어가는지 그리고 셀의 갯수가 몇개인지가 들어가는 기본 메소드가 존재한다.

이를 통해서 셀의 갯수와 정으를 했다면 해당 셀의 위치를 잡아주어야 하는데 이를 위해서 사용하는 클래스이다.

  1. numberOfSection : 섹션의 수
  2. numberOfItemsInSection : 하나의 섹션에 들어갈 아이템의 수
  3. cellForItemAt : 아이템의 정의(cell 을 리턴한다)

cellForItemAt

func collectionView()->UICollectionViewCell{
	let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "셀이름",for: indexPath) as! "셀이름"
	return cell
}

을통해서 셀을 리유저블셀에 넣고 안에 들어갈 아이템을 정의하게 된다.

Layout-related object

레이아웃에 관련된 클래스는 기본이 UICollectionViewLayout이며, 이것의 하나의 유형이 UICollectionViewFlowLayout,그리고 이를 응용한것이 UICollectionViewCompositionalLayout이다.

UICollectionViewLayout

Untitled.png

Untitled.png

A layout object determines the placement of cells, supplementary views, and decoration views inside the collection view’s bounds and reports that information to the collection view. The collection view then applies the provided layout information to the corresponding views so that they can be presented onscreen.

즉 기본적으로 cell, supplementary views, decoration views를 묶은 collection viewd의 information 을 묶은 layout object이다.

cell

셀은 그냥 진짜 nib파일로 만들던 collectionViewCell로 만들던 동일한 그냥 cell이다.

supplementary view

여기가 좀 어려운데 supplementary view는 headerview와 footerview가있다.

하지만 이거는 그냥 일반 뷰를 넣으면 안되고, collection reusable view를 사용해서 넣게 된다.

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) ->
        UICollectionReusableView {
     switch kind {
        case UICollectionView.elementKindSectionHeader:
            let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "reusableView", for: indexPath)
            return headerView
        default:
            assert(false, "응 아니야")
     }
}

이 메소드를 collectionView datasource프로토콜에서 선언해주어야 한다.

  • 헤더뷰인지, 푸터뷰인지를 확인하는 부분이 string으로 값을 받아오는 kind이다.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        let width: CGFloat = collectionView.frame.width
        let height: CGFloat = 20
        return CGSize(width: width, height: height)
}

decoration View

콘텐츠가 스크롤 되는 컬렉션뷰에 대한 배경을 꾸밀 때 사용한다. 레이아웃 객체는 데코레이션 뷰를 사용하여 커스텀 배경 모양을 구현할 수 있다.

  • 이러한 UICollectionViewLayout은 셀에 대한 정렬을 할수가 없다.
  • 이를 위해서 다음과 같은 클래스가 생성되었다.

UICollectionViewFlowLayout

UICollectionViewFlowLayout은 UICollectionViewLayout에서 셀을 원하는데로 정렬을 할수 없었기 때문에 이를 해결하기 위해서 파생된 클래스이다. (UICollectionViewLayout을 상속받고 있음)

Untitled.png

Untitled.png

flowLayout은 이렇게 레이아웃을 따라서 셀을 채우게 되고, 해당 위치의 행에서 셀이 최대한 찼으면 새로운 행을 만들어서 거기에 레이아웃 프로세스를 계속해서 이어나가는 형태의 레이아웃이다.

스크롤 방향은 다음과 같은 코드로 바꿔줄수 있다.

flowLayout = collectionViewLayout as? UICollectionViewFlowLayout { flowLayout.scrollDirection = .Horizontal }
flowLayout = collectionViewLayout as? UICollectionViewFlowLayout { flowLayout.scrollDirection = .Vertical }

플로우 레이아웃 설정 순서

플로우 레이아웃 구성 단계

1. 플로우 레이아웃 객체를 작성해 컬렉션뷰의 레이아웃 객체로 지정합니다.
2. 셀의 너비와 높이를 구성합니다.
3. 필요한 경우 셀의 간격을 조절합니다.
4. 원할 경우 섹션 헤더 혹은 섹션 푸터를 크기를 지정합니다.
5. 레이아웃의 스크롤 방향을 설정합니다.
  • 플로우 레이아웃은 모든셀에 동일하게 적용된다.

셀사이즈지정 메소드

collectionView:layout:sizeForItemAtIndexPath:

동적으로 설정하고 싶다면 다음의 메소드를 사용ㅎ게 된다.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 10 * Int.random(in: 5...10) , height: 10 * Int.random(in: 5...10))
    }

플로우레이아웃 셀간의 간격 설정하는 메소드

Untitled.png

Untitled.png

UICollectionViewDelegateFlowLayout에서 설정하게 되는 메소드이다.

collectionView(:layout:minimumLineSpacingForSectionAt:) : actual line spacing(실제 간격) collectionView(:layout:minimumInteritemSpacingForSectionAt:) : minimum line spacing(최소간격)

content마진주기

Untitled.png

Section Insets을 이용해서 컨텐츠에 마진을 주게 되고, 이를 통해서 섹션에 들어갈, 각 라인별 cell의 수를 정할수 있게 된다.

  • 셀에 대한 정렬과 포지셔닝에 대한 문제는 해결했지만, 이보다 더 복잡한 섹션별로 다양한 방향의 스크롤과 정렬에 대해서는 여전히 어려움이 존재한다.
  • 이러한 부분을 해결하기 위해서 ios13부터 지원하게 되는 기능이 바로 UICollectionViewCompostionalLayout이다.

bookmark

bookmark

bookmark

반응형