UICollectionViewCompositionalLayout에 대하여

French Marigold·2023년 7월 19일
0

iOS

목록 보기
2/3

CollectionViewLayout의 종류


CollectionView에는 두 가지 종류가 있다.

1. UICollectionViewFlowLayout

이 CollectionViewLayout은 셀을 현재 행에서 채워나가되, 화면의 공간이 부족해지면 새로운 행을 생성해서 셀들을 추가하는 방식이다.

스크린샷 2023-07-05 오후 5 54 50

위의 그림처럼 스크롤의 방향에 따라 최대한 많은 셀들을 배치한 후, 화면에 다 채우지 못하면 다음 행으로 넘어가 셀들을 추가한다.

또한 CollectionViewFlowLayout은 두 가지 방법으로 컬렉션 뷰 셀의 width와 height를 정해줄 수 있다.

1) itemSize

스크린샷 2023-07-12 오후 9 02 33

2) UICollectionViewDelegateFlowLayout를 준수하여 메소드를 구현

스크린샷 2023-07-12 오후 9 07 19

CollectionViewFlowLayout은 모든 셀에 대하여 width값과 height값을 정해주는 것으로,


어떤 특정 셀의 width값과 height값만 다르게 지정하는 것은 불가능하다.


(물론 width: 10 Int.random(in: 5...10) , height: 10 Int.random(in: 5...10) 이런 방식으로 각 셀의 크기를 다르게 해 줄 수는 있긴 하다.)

가장 전통적인 방식의 레이아웃으로 애플은 웬만하면 이 레이아웃 사용하기를 권장하고 있다. 그러나...


📌 CollectionViewFlowLayout의 문제점


현대적인 앱의 레이아웃은 정말 복잡하다. 각 레이아웃의 크기나 모양이 전부 다 다르며 일정하지 않다.


앱 스토어 레이아웃과 같은 레이아웃을 보면 레이아웃의 구성이 전부 다 다른 것을 확인할 수 있다.

스크린샷 2023-07-12 오후 9 07 19

CollectionViewFlowLayout은 위와 같은 레이아웃을 구성하기에 좋은 선택지는 아니다.


CollectionViewFlowLayout은 각 섹션 별로 크기나 형태를 다르게 만들어주기가 까다롭고 어렵기 때문이다.


2. UICollectionViewCompositionalLayout

위의 예시와 같이, CollectionViewFlowLayout이 갖는 문제점을 해결하고자, iOS 13 버전에서 도입된 레이아웃이 바로 CollectionViewCompositionalLayout이다.


위에서 앱 스토어 에시를 다뤘듯이, 이 레이아웃은 복잡한 섹션을 구성하기에 적합한 레이아웃 방식이다.

CompositionalLayoutExample


CollectionViewCompositionalLayout의 구성요소


위와 같은 복잡한 레이아웃을 구성하기 위해서 CollectionViewCompositionalLayout은 다음과 같이 구성되어 있다.

1. item: 컬렉션 뷰를 이룰 때 쓰이는 한 개의 구성요소.


UICollectionViewCompositionalLayout에서 Item의 크기를 정하는 방법은 세 가지이며
Item을 생성할 때에는 **NSCollectionLayoutItem(layoutSize:)** 메소드를 사용한다.
layoutSize에는 각각의 Item의 크기를 정해줄 수 있는 NSCollectionLayoutSize(widthDimension:heightDimension:) 메소드가 들어가면 된다.

1-1) .absolute:

NSCollectionLayoutSize(widthDimension: .absolute(10), heightDimension: .absolute(10))


이런 방식으로 사용하며 고정 크기를 의미한다.


즉, 우리가 원래 사용하듯이 width 10, height 10을 의미하는 것임.

1-2) .estimated:

NSCollectionLayoutSize(widthDimension: .estimated(10), heightDimension: .estimated(10))


이런 방식으로 사용하며 대략적인 크기를 의미한다.


예를 들어 width를 일단 10으로 정해놓았지만 상황에 따라서 컴파일러가 크기를 약간 조절할 수 있다는 의미다.

1-3) .fractional:

NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.4), heightDimension: .fractionalHeight(0.7))


이런 방식으로 사용하며 비율로 크기를 조정한다.


0 에서 1까지의 비율이 있는데 "1은 Item을 꽉 채우는 것을 의미한다." ⭐️


좀 더 쉽게 설명하자면 fractionalWidth(1)은 Item의 가로 부분을 꽉 채우겠다는 의미이고


fractionalHeight(1)은 Item의 세로 부분을 꽉 채우겠다는 의미이다.
<br.
예를 들어 fractionalWidth(0.5)는


"Item 반은 이미지 화면이 나오지만 반은 흰 공백 화면으로 나오는 것을 의미한다."


fractionalWidth(0.3)은 "Item의 30%만 이미지 화면이 나오고 70%는 흰 공백 화면으로 나오는 것을 의미한다."


2. group: Item을 모두 합쳐놓은 구성요소.


즉, Group은 여러 개의 Item들을 담고 있는 그릇이라고 생각하면 된다.
Group은 여러 개의 Item들을 어떤 방향으로 묶을지도 정해줘야 한다.
가로로 Item들을 묶을 때엔 .horizontal, 세로로 Item들을 묶을 때엔 .vertical을 사용한다.
Group을 생성할 때에는 두 가지 메소드로 또 나뉘게 된다.

1️⃣ NSCollectionLayoutGroup.horizontal(layoutSize:repeatingSubitem:count)

1-1) layoutSize:

Group의 전체 크기를 정해줄 수 있는 NSCollectionLayoutSize(widthDimension:heightDimension:) 메소드가 들어가면 된다.

1-2) subitem:

어떤 item이 들어갈 것인지. 보통 위에서 만들어 놓은 item을 여기에 할당한다.


한 Group 내에 몇 개의 item이 들어가는지에 따라서 subitem의 .fractional 영역을 조절해줘야 한다.

1-3) count:

몇 개의 item이 들어갈 것인지.


예를 들어 4이라고 적으면 item 4개가 한 Group 안에 들어가게 된다.


따라서 한 Group 내에 Item 4개가 다 들어갈 수 있도록 개발자가 임의로 Item들의 .fractional 영역을 조절해줘야 한다.


(layoustSize:repeatingSubitem:count:) 파라미터를 보통 사용하는 경우는 똑같은 Item들이 반복되어 나열되어야 할 때이다.

2️⃣ NSCollectionLayoutGroup.horizontal(layoutSize:subitems:)

2-1) layoutSize:

Group의 전체 크기를 정해줄 수 있는 NSCollectionLayoutSize(widthDimension:heightDimension:) 메소드가 들어가면 된다.

2-2) subitems:

어떤 item이 들어갈 것인지. 이건 똑같다.


다만 subitems 파라미터를 보통 사용하는 경우는


Group 내에 또다른 Group을 커스텀하여 넣고 싶을 때 사용한다.


⭐️⭐️ 이 두 메소드를 사용할 때 주의할 점 ⭐️⭐️

"item들이 몇 개 들어가냐에 따라서 개발자가 ⭐️item⭐️의 .fractionalWidth를 조절해줘야 한다."


예를 들어 Group 내에 item을 두 개를 넣는다고 가정하면


"item"의 .fractionalWidth는 반드시 0.5여야 한다. (0.5 + 0.5)로 Group을 채워야 하기 때문.


만일 Group 내에 item을 4개 넣는다고 가정하면


"item"의 .fractionalWidth는 반드시 0.25여야 한다. (0.25 * 4)로 Group을 채워야 하기 때문.


UICollectionViewCompositionalLayout에서 Group의 크기를 정하는 방법은 역시 세 가지이며


layoutSize에는 NSCollectionLayoutSize(widthDimension:heightDimension:) 메소드가 들어가면 된다.

1-1) .absolute

NSCollectionLayoutSize(widthDimension: .absolute(10), heightDimension: .absolute(10))


이런 방식으로 사용하며 고정 크기를 의미한다.


즉, 우리가 원래 사용하듯이 width 10, height 10을 의미하는 것임.

1-2) .estimated

NSCollectionLayoutSize(widthDimension: .estimated(10), heightDimension: .estimated(10))


이런 방식으로 사용하며 대략적인 크기를 의미한다.


예를 들어 width를 일단 10으로 정해놓았지만 상황에 따라서 컴파일러가 크기를 약간 조절할 수 있다는 의미다.

1-3) .fractional

NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.4), heightDimension: .fractionalHeight(0.7))


이런 방식으로 사용하며 비율로 크기를 조정한다.


0 에서 1까지의 비율이 있는데 "1은 Group이 화면을 꽉 채우는 것을 의미한다." ⭐️


예를 들어 fractionalWidth(1)은 Group의 가로를 꽉 채우는 것을 의미하며


fractionalWidth(0.3)은


"Group의 30%는 채우고 70%는 다른 Group으로 채우겠다는 의미이다."


3. section

Group을 모두 합쳐놓은 구성요소. 만들어놓은 Group을 Section에 할당하고


UICollectionViewCompositionalLayout을 리턴할 때 Section을 넘겨주면 된다.


NSCollectionLayoutSection(group:) 메소드를 통해서 이제껏 만든 group을 할당한다.


위의 모든 내용을 코드로 옮기면 다음과 같다.
  1. 먼저 CollectionView를 메모리에 올린다. 이 때, CollectionViewLayout의 형태를 리턴값이 UICollectionViewCompositionalLayout인 메소드 makeCompositionalLayout()를 할당한다.
    스크린샷 2023-07-05 오후 6 47 20

  2. Item 값을 설정

스크린샷 2023-07-05 오후 6 48 53
  1. Group 값 설정
스크린샷 2023-07-05 오후 6 48 53
  1. Section과 Return 값을 마지막으로 설정해준다.
스크린샷 2023-07-05 오후 6 48 53

결과물



출처 및 문서 참고

profile
꽃말 == 반드시 오고야 말 행복

2개의 댓글

comment-user-thumbnail
2023년 7월 19일

잘 봤습니다. 좋은 글 감사합니다.

1개의 답글