Toy Project/One Piece (iOS)

8. Collection View: 여러개의 아이템을 보여주는 View

개발자킹콩 2021. 2. 9. 22:29

CollectionView: 여러개의 아이템을 보여주는 View

 

 

 

 

List를 구현하기 위해 TableView를 사용했었다.

TableView의 경우 표현의 한계가 존재한다.

하나의 Column만 존재하기에 여러개의 아이템을 넣고 싶으면 사용할 수 없다.

 

위의 어플에서는 한 행안에 다양한 데이터들이 존재한다.

 

 

 


 

 

 

CollectionView의 특징

 

  1. Column을 한개 이상 가질 수 있다.
  2. 각 데이터의 나열을 수직 혹은 수평으로 지정할 수 있다.
  3. CollectionView의 데이터는 CollectionViewCell 을 통해 표현이 되며 다양한 스타일로 표현될 수 있다.
  4. UITableView에 비해 데이터의 나열이 자유롭기 때문에, 많은 데이터를 보여주는 경우 CollectionView를 커스터마이징하며 사용한다. 

 

 

 

UICollectionViewLayout: 

CollectionView의 경우 이렇게 자유로운 레이아웃을 가진다. 

때문에 Layout을 전문적으로 관리하는 객체가 필요하며 이 객체를 의미한다.

우리는 UICollectionViewLayout을 상속받아 우리만의 Layout객체를 만들 수 있다.

 

참고사항

애플에서 제공하는 Layout객체 : UICollectionViewFlowLayout

우리가 만들 사항들은 이것만 사용해도 충분히 만들 수 있다.

 

CollectionView의 구현은 TableView에서 적용했던, DataSource, Delegate 프로토콜을 사용하며 CollectionView에 맞는 코드를 작성하면 된다.

 

 

 

 


 

auto layout 복습한다고 생각하고~

 

 

Object Library에서 CollectionView를 선택하고 Cell의 사이즈를 200, 350으로 지정하자.

 

 

 

 

 

그리고 한 Cell안에는 ImgView와 Label을 삽입한다.

Auto layout은 바로바로하자

 

 

 

 

여기서 imageView의 크기는 Aspect ratio 7:10으로 지정하였고, leading, top, tailing은 각각 0으로 지정하였다.

Luffy는 content view와 leading를 20으로 맞추고, imageView와의 수직적 거리인 vertical spacing를 10으로 설정하였다. 한마디로 그림과의 거리가 10인것이다.

여기서 밑의 label의 경우 좌측정렬을 한것처럼 하기위해 위의 label과 leading를 맞춘다.

그리고 vertical spacing을 10으로 설정하여 위치를 지정하였다.

이 말을 이해 못하면 하고 돌아오거라.

 

 

여기서 저번에 프로젝트 하면서 이상하게 요류가 계속나서 고생했던것!!! —> CollectionView와 ViewController을 연결해주어야 한다, TableView와 같이 DataSource와 Delegate로 연결 

 

 

이렇게 되면 현재 StoryBoard에서 해야할 일은 끝났고, 코드에서 CustomCell을 만들고 클래스 지정만 해주면 진짜 끝이다.

 

 

 

 


 

코드구현

 

 

우리는 아래와 같은 화면을 띄울 것이다.!!!

 

 

 

이제 BountyViewController은 ViewController과 UICollectionViewDataSource, UICollertionViewDelegate, UICollectionViewDelegateFlowLayout 을 상속받는다.

 

UICollectionView 같은 경우 아이템들을 자유롭게 배치하도록 하기위해 FlowLayout객체가 존재하는데, FlowLayout에 대한 정보도 구현해줄 필요가 있기에 넣어준다.

디바이스 마다 다르게 표현되어야 하는데 Cell의 크기가 다르게 표현되어야 할텐데 이를 계산해주기 위해 삽입했다.

 

 

 

 

 

 

 

 

 

 

 

이렇게 넣어주면 해당 protocol에 맞게 구현이 들어가면 된다.

 

 

 

 

 

cell에서 몇개를 표현하는가와 어떻게 표현할 것인가에 대한 정보는 아래의 코드와 같이 나타난다.

 

 

 

여기서 Identifier을 지정할 때 오타나지 않도록 주의하자!! 뭔오류인가 했네..

 

 

 


 

Custom Cell

 

 

 

그렇다면 GridCell을 정의하고 해당 UIComponents 를 storyboard와 연결시켜주자.

 

 

 

이렇게 무작정 연결하게 되면 연결이 안될 것이다.

이유는?? 해당 CollectionView에서 GridCell을 Cell로 사용할것이라는 지정을 해주지 않았기 때문이다.

 

 

 

 

 

 

이렇게 지정해주면 우리가 만든 StoryBoard의 UIComponents는 이제 해당 코드의 변수들과 연결이 될 수 있는 것이다.

 

 

 

 


 

 

 

그럼 이제 Cell이 선택이 되었을 때 동작을 제어하는 코드를 작성해보자

 

 

 

우선 performSegue를 통해 해당 indexPath에 해당하는 Cell 이 선택이 되었을 때, 

showDetail이라는 Segue를 알았다면 sender을 통해 해당 item이 몇번째 데이터에 해당하는지에 대한 정보는 sender을 통해 전달하게 된다.

 

그렇게 되면 DetailViewController에서는 데이터를 받게되는데 실제는 받는 코드는 존재하지 않는다. 이건 prepare라는 method에서 작성하게 되는데, 해당 segue의 id 가 showDetail이라면 목적지를 down casting하고 BountyViewController에서 DetailViewController의 변수를 미리 들고와서 거기에 데이터를 저장하는 구조가 되는 것이다.

 

 

 

 

 

 

 

 

 

 

 

이렇게 되면 코드는 동작하게 되지만  Cell size가 계산되지 않아서 2개가 아닌 1개씩 보여지게 된다.

 

 

이제 이것을 계산하여 데이터가 2개씩 보여지게 되고, 이는 여러 디바이스 모두에 해당되게 코드를 구현해보자.