본문 바로가기

IOS

UICollectionViewCell Dynamic Frame 다루기

마주한 문제상황

UICollectionView를 통해서는 항상 Width와 Height가 일정하게 고정되어 있는 형태만 구현했었는데, 아래와 이미지와 같이 cell Height가 dynamic 해야하는 형태의 구현을 하게 되었습니다.

기획의 의도를 간략하게 표현한 그림인데, 중요하게 지켜야 할 2가지 조건이 있습니다.

  • 하나의 UICollectionViewCell의 width는 CollectionView의 width를 2분의 1을 차지한다.
  • UICollectionViewCell의 height는 내부의 text와 화면 해상도에 따라 UILabel이 최대 2줄로 표현되며 그 높이에 맞게 dynamic하게 결정 되어야한다.

구현해야했던 기획화면

저에게 가장 허들이었던 것은 "UICollectionViewCell의 height를 Dynamic하게 결정한다" 즉, 처음으로 Self Sizing이 가능한 UICollectionViewCell을 구현해야하는 것이 었습니다.

참고한 Reference

이미 많은 분들이 UIColleoctionViewCell Self-Sizing에 대해서 많은 글을 작성해주셔서 다양한 글들을 읽어보다. 밑의 블로그 글을 만나게 되었습니다. (검색한 키워드 : uicollectionviewcell dynamic height)

https://medium.com/swift2go/implementing-a-dynamic-height-uicollectionviewcell-in-swift-5-bdd912acd5c8

 

Implementing a Dynamic Height UICollectionViewCell in Swift 5

Creating a UICollectionViewCell to have a dynamic height based on font size and image aspect ratio

medium.com

해당 블로그를 참고하여 학습한 내용과 간단한 Sample 앱을 만들어 보겠습니다.

위 블로그에서 제안한 방법은 UICollectionViewFlowLayout의 2가지 함수와 UICollectionViewCell의 1가지 함수를 Customize 하는 것이 었습니다.

SampleProject Setup

기본이 되는 Sample Project를 셋업합니다.

해결방안 구현1 > Customize UICollectionViewFlowLayout

UICollectionViewFlowLayout의 Document를 살펴보면 첫 문단에서 Dynamic한 cell을 지원하기 위해서는 UIColloectionViewFlowLayout을 사용해야할 것을 감지할 수 있습니다.

A flow layout is a type of collection view layout. Items in the collection view flow from one row or column (depending on the scrolling direction) to the next, with each row containing as many cells as will fit. Cells can be the same sizes or different sizes.

 

UICollecitonViewFlowLayout Customize 대상 함수:

해당 함수들에서 위에서 언급한 문제 중 한가지가 구현됩니다.

하나의 UICollectionViewCell의 width는 UICollectionView의 width를 2분의 1을 차지한다.

Implement Commit : https://github.com/wjdgkals23/UICollectionViewDynamicFrame/commit/1f83d49ac443952d080b3e32558df62c394fc936

해결방안 구현2 > UICollectionView Configuration

이제 위에서 SubClassing한 UICollectionViewFlowLayout을 UICollectionView에 적용합니다.

유의해야할 점은 SelfSizing을 이용하기 위해서 UICollectionViewFlowLayout Property 중 estimatedItemSize에 UICollectionViewFlowLayout.automaticSize 옵션을 주어야합니다.

Implement Commit : https://github.com/wjdgkals23/UICollectionViewDynamicFrame/commit/ad4e89e9ac62ea44e26d90c82573c34c1129bfa4

해결방안 구현3 > Customize UICollectionViewCell

이제 마지막으로 UICollectionViewCell을 Customize합니다. 해결방안 구현1에서 작성한 함수들을 통해 최종적으로 계산된 layoutAttributes를 적용하는 함수를 override 합니다.

위 함수에서 위에서 언급한 마지막 문제가 구현됩니다.

UICollectionViewCell의 height는 내부의 text와 화면 해상도에 따라 UILabel이 최대 2줄로 표현되며 그 높이에 맞게 dynamic하게 결정 되어야한다.

내부에서 contentView를 사용하여 dynamic하게 Height를 계산하고 Cell의 Frame을 수정해줍니다.

여기서 유의할 점은 UICollectionViewCell에 UILabel을 더할 때, 반드시 contentView에 addSubView를 해주어야합니다.

그 이유는 contentView의 설명을 보면 알 수 있습니다.

When configuring a cell, you add any custom views representing your cell’s content to this view. The cell object places the content in this view in front of any background views.

Implement Commit : https://github.com/wjdgkals23/UICollectionViewDynamicFrame/commit/5db792e690c3391078f4d4ae52bcc56678d31e02

이런 방식으로 구현을 하면 Width와 Height를 Self-Sizing 할 수 있습니다.

구현 결과물

 

'IOS' 카테고리의 다른 글

Jenkins PipeLine 적용기  (0) 2021.06.01
내가 원하는 개발 패턴 만들어보기 PART1  (0) 2021.04.17