먹고 기도하고 코딩하라

[UIKit] TableView, CollectionView 비교하기 본문

앱/Swift

[UIKit] TableView, CollectionView 비교하기

사과먹는사람 2022. 11. 27. 00:03
728x90
728x90

네줄요약 :

테이블뷰는 단일 컬럼만 가능하다는 제약 사실을 기억하고 결정하자.

둘 사이의 가장 큰 차이점은 레이아웃이다.

테이블뷰를 사용해도 될 요구사항에는 굳이 컬렉션뷰를 사용하지 말고 테이블뷰를 쓰는 게 좋다.

이유는, 컬렉션뷰는 보일러플레이트 코드 때문에 코드 양이 늘어나기 때문이다.

 

 

일단 TableView와 CollectionView 간 공통점과 차이점을 간단히 정리하면 이 정도 쓸 수 있다.

  TableView CollectionView
공통점 * 셀을 기반으로 여러 데이터를 표현할 수 있다. (테이블뷰는 UITableViewCell, 컬렉션뷰는 UICollectionViewCell)
* UIScrollView의 서브 클래스이다.
* dataSource, delegate 구현이 필요하다. (delegate는 필수는 아니다)
* 섹션이 있다.
수직, 수평 방향 스크롤이 가능한가? 불가능. 수직 방향만 가능하다. (*하지만, TableViewCell 안에 CollectionView를 넣는 방식으로 섹션 안에서 가로 방향 스크롤을 할 수는 있다.) 가능
뷰에 기본 스타일이 존재하는가? 존재한다. plain, grouped, insetGrouped 스타일을 UITableView.Style enum으로 제공하고 있다. 존재하지 않는다.
셀에 기본 스타일이 존재하는가? 존재한다. TableViewCell은 default, value1, value2, subtitle 등의 기본 스타일들을 UITableViewCell.CellStyle enum으로 제공하고 있다. 존재하지 않는다.

 

언뜻 보기에, CollectionView는 TableView가 할 수 있는 거의 모든 것을 대체할 수 있는 것 같기도 하다. 그럼 왜 CollectionView를 안 쓰고 TableView를 쓰는 걸까. 조건을 생각해봤을 때 '이건 TableView가 더 좋을 것 같아, 저건 CollectionView가 좋겠다'라고 생각한 적은 있지만, 그 직관이 과연 어디에 기초하는가는 한 번쯤 생각해볼 법한 문제인 듯하다. 

 

일단 문서에서 테이블뷰와 컬렉션뷰를 뭐라고 소개하고 있는지 살펴보자.

UITableView
A view that presents data using rows in a single column.
단일 열 안에 행들을 사용해 데이터를 표현하는 뷰. (쉽게 말해, 수직으로 쌓인다는 뜻이다)
UICollectionView
An object that manages an ordered collection of data items and presents them using customizable layouts.
순서가 있는 데이터 항목 모음을 관리하고, 커스텀 가능한 레이아웃을 통해 표현하는 객체.

 

일단 한줄소개에서는 이 둘의 레이아웃이 다를 거라는 걸 예측할 수 있다. 

 

 

옛날에 쓰인 질문이지만 추천을 많이 받은 스택오버플로우 글을 한 번 살펴보자.

질문자는 iOS 6에서 새롭게 도입된 UICollectionView는 UITableView의 업그레이드 버전 같은데 언제 UICollectionView를 써야 하느냐, CollectionView로 TableView가 할 수 있는 일을 할 수 있다면 사람들은 왜 TableView를 쓰느냐고 묻고 있다.

채택된 답변을 간단히 요약하면, 뭘 쓸지는 '요구사항'에 달렸다. 보통 그리드 형식으로 이미지를 보여주거나 할 때는 UICollectionView를 사용하는데, 이유는 TableView로 구현하려면 굉장히 복잡한 로직이 필요하기 때문이다. 

다른 답변은 TableView로 할 수 있다면 TableView를 쓰고, 테이블뷰를 썼을 때 코드가 더 길어지거나 아예 할 수 없는 작업이라면 컬렉션뷰를 쓴다고 자신만의 기준을 공유했다. (음.. 나도 이런 기준이었던 것 같다)

테이블뷰는 수직 방향 스크롤만 가능하고, 2개 이상의 column을 쓸 수 없는 뷰라는 제약이 있다. 단, 테이블뷰로 할 수 있는 일이라면 테이블뷰를 쓰는 이유는 컬렉션뷰를 테이블뷰처럼 사용하려고 할 때 보일러플레이트 코드(컬렉션뷰 사용을 위한 일종의 준비 코드)가 더 많이 필요하기 때문이라고 한다. 

 

한마디로.. 구현할 목록의 레이아웃 요구사항에 따라 뭘 쓸지 결정하는 게 좋다는 얘기다.

 

여담으로, 컬렉션뷰의 레이아웃 커스텀을 세밀하게 할 수 있게 도와주는 것으로 레이아웃 객체가 있다. UICollectionViewLayout 추상 클래스의 서브클래스인 UICollectionViewFlowLayout이나 UICollectionViewCompositionalLayout 등을 사용하면 된다. CompositionalLayout의 장점은 섹션별로 레이아웃을 달리 잡을 수 있다는 점이다. 그래서 유튜브 뮤직처럼 섹션별로 레이아웃이 다른 뷰를 작업할 때는 Compositional로 레이아웃 객체를 생성하고 섹션 번호나 기타 identifier 등으로 분기해서 레이아웃을 나타내주면 좋다.

 

 

+ 번외 : 스크롤되는 1차원 레이아웃에서는 뭘 써야 할까? (Feat. UIStackView)

넷플릭스나 왓챠, 윌라와 같은 콘텐츠를 제공하는 서비스의 경우 다음과 같이 영상이나 책의 포스터, 표지 같은 썸네일을 가로로 쭉 배열해서 스크롤할 수 있도록 만든 레이아웃이 많다.

 

보면 아마 컬렉션뷰로 만들었겠지 하는 생각이 든다.

그런데 잘 보면, 이 레이아웃은 UIStackView로 만들 수도 있지 않을까? 격자도 아니고, 그냥 1차원 횡방향 스크롤 레이아웃 아닌가? 스크롤뷰에 스택뷰 심으면 되는 게 아닐까? CollectionView를 써야 할까?! 

나 역시도 개인 앱을 제작할 때 비슷한 레이아웃으로 데이터들을 여러 개 뿌려야할 때가 있었는데, '이거.. 스택뷰로 할 수 있지 않나..' 생각해본 적이 있다.  

 

이런 의문은 나만 가진 게 아니었다. 꽤 지났지만 아마 지금도 유효할 것 같은 스택오버플로우의 질문 글에서 질문자는 direction이 horizontal이거나 vertical인 스택뷰(1차원)와 컬렉션뷰 간의 차이가 뭐냐고 물었다. 컬렉션 뷰는 둘 다 되는데 사람들은 왜 스택뷰를 쓰냐, 스택뷰는 컬렉션뷰가 못 하는 뭔가 특별한 걸 하냐는 게 요지이다. 

upvote를 가장 많이 받은 답변에서는 유스케이스에 따라 컬렉션 뷰의 복잡함이 필요없다면 스택뷰를 쓸 수도 있다고 설명하고 있다. 하긴 스택뷰는 데이터소스나 delegate가 없으므로 그에 따른 부차적인 코드나 셀 register, layout 등록 등도 딱히 필요 없다.

그 다음 답변에서는 컬렉션 뷰는 셀이 있고, 데이터를 표현하는 작업 등을 하며 스택뷰는 컨테이너 뷰로서 뷰들을 레이아웃하는 데 사용된다고 설명하고 있다. 컬렉션 뷰는 데이터 중심이고 스택뷰는 레이아웃에 중점을 두고 있다고 설명한다.

 

개인적으로는 스택뷰와 컬렉션뷰는 근본 자체가 다르다고 생각한다.

레이아웃 구현은 스택뷰가 더 비슷하게 할 수 있을지는 몰라도, 컬렉션뷰는 오히려 데이터소스와 delegate가 있다는 점에서 스택뷰보다는 테이블뷰와 더 비슷하다. 또한 스택뷰는 UIScrollView를 상속받지도 않았다. (상속받아야 그나마 컬렉션뷰랑 좀 비슷해지는 수준)

그리고 테이블뷰와 컬렉션뷰의 대 장점들 중 하나로 셀을 재활용한다는 점이 있는데 스택뷰는 그렇지 않다. 스택뷰에 들어가는 뷰들은 뷰가 로드될 때 메모리에 전부 올라와야 한다. 이게 뷰가 10개, 20개 정도일 때는 그렇게 큰 문제가 되진 않겠지만 100개 단위가 넘어간다면 그렇게 많은 뷰들을 항상 유지해야 하므로 메모리 낭비이다. 따라서, 굳이 스크롤뷰에 스택뷰를 올려서 사용할 이유는 없을 것 같다는 게 내 생각이다.

 

-> 결론 : 나도 저 고민을 하다가 결국에는 컬렉션뷰로 구현하게 됐다.

레이아웃만 생각하면 스택뷰를 사용할 수도 있었지만, 내 경우에는 카드 뷰들 중 하나를 선택하면 다른 뷰컨으로 넘어가야 했는데 스택뷰로는 그걸 달성하기 조금 까다로웠다. 컬렉션뷰는 delegate의 didSelectItemAt 구현하면 끝이라 훨씬 좋았다!

 

 

 

References

 

728x90
반응형
Comments