티스토리 뷰

개요


Pinterest나 AppStore같은 어플에 사용되는 CardView를 collection view를 사용해서 구현해보자.

보통 카드 형태로된 뉴스피드를 보여주는 어플리케이션에서 주로 사용하기 때문에 예제 어플리케이션을 구현할 때도 관련된 이름을 사용한다.






Storyboard 구성


먼저 어플리케이션을 구성하는 전체적인 Storyboard를 보자. NavigationController를 사용하기 때문에 기본화면으로 MainViewController와 cell을 선택했을 때 진입하게 될 NewsViewController를 추가한다.

  1. main view에는 선택할 수 있는 cell들이 보여지도록 만들것이다. 먼저 UICollectionViewController를 상속받는 MainViewController 클래스를 정의하고 storyboard에서 해당 클래스를 사용하도록 설정한다.

  2. news view는 cell을 선택하면 진입하는 view로 뒤로가기위한 navigation bar와 cell이 가지고있던 view의 상세정보가 보여지도록 만들것이다. 따라서 UIViewController를 상속받는 NewsViewController 클래스를 정의하고 storyboard에서 해당 클래스를 사용하도록 설정한다.

  3. transition 효과를 줄 때 기존에 있는 main view가 애니메이션 중에도 뒤에서 계속 보이도록 하기 위해 news view의 배경색은 투명하게 설정한다.

  4. main view를 구성하는 cell들 또한 우리가 원하는 동작을 하도록 커스터마이징 할것이다. UICollectionViewCell을 상속받는 CardCell 클래스를 정의하고 해당 클래스를 사용하도록 설정한다. collection view는 cell을 생성할 때 클래스 뿐 아니라 identifier 값을 사용해서 구분하기 때문에 identifier 또한 “CardCell”로 설정한다.

  5. 화면 전환을 시킬 때 segue를 사용하는데 이 또한 identifier로 각 segue를 구분하기 때문에 “Spread”로 설정해서 원하는 segue를 찾을 수 있도록 한다.




Card


cell을 구성하는 정보들을 관리하는 CardModel 클래스를 정의해보자. 정보는 CardInfo로 이름지은 구조체에 담겨있고 model클래스는 이 Info들을 생성 및 관리하고 view에게 전달하는 동작을 수행한다.

CardInfo는 간단하게 배경색과 제목, cell의 높이정보를 저장한다. 높이정보를 cell마다 가지고있기 때문에 원하는 만큼 다양한 크기의 cell을 생성할 수 있다.


제대로된 모델 클래스라면 서버로부터 정보를 가져오거나 파일에서 정보를 가져와야 하지만 예제인만큼 생성자에서 임의로 5개의 카드정보를 생성하고 각 카드는 서로 구분할수있도록 다른 정보로 초기화한다.


CardCell 클래스는 UICollectionViewCell을 상속받아 만들며, 커스텀할 수 있도록 위처럼 outlet을 연결한다.


  1. 전달받은 CardInfo 정보를 토대로 제목과 배경색을 설정한다.

  2. cell의 높이와 무관하게 heightConstraint 값을 cell의 높이값으로 수정하는데 이 이유는 card view를 통째로 옮겨서 transition 효과를 줄 때 card view의 크기가 변하더라도 headline을 구성하는 view의 높이는 고정시키기 위해서이다. 이에 대해서는 뒤쪽에서 더 자세히 설명하기로 하고 여기서는 info의 높이값에서 layoutMargin을 뺀 것에 집중하자.


CardCell 클래스에서 height constraint 값을 cell의 height 값으로 그대로 지정하면 위 그림처럼 아래로 벗어나게 되고 원하는 모습으로 그려지지 않는다. 따라서 cell의 height값에서 layout margin을 뺀 값으로 설정하여 card view에 딱 맞는 크기로 보이도록 하는 것이다.

그림에서는 headline view가 card view보다 작아지기 때문에 뒤에있는 card view가 보일 것 같지만, 자식인 headline view는 layout margin 크기만큼 안쪽으로 들어가있기 때문에 실제로 실행해보면 뒤에있는 card view가 보이지않게 딱 맞는것을 볼 수 있다.




Layout


만들고자 하는 어플리케이션은 크기가 제각각인 cell을 가지고 있기 때문에 기본적으로 제공되는 flow layout을 적용할 수 없다. 따라서 우리가 원하는 모습으로 만들기 위해 UICollectionViewLayout 클래스를 상속받는 MainCollectionViewLayout 클래스를 구현하여 사용한다.

CollectionViewLayout이 동작하는 원리는 아래 그림을 통해 알 수 있다.

그림에서 볼 수 있듯이 collection view는 자신의 layout 객체에게 cell들을 어디에 배치하고 어느정도 크기로 그릴지 질문을 하고 layout 객체는 layout attribute를 통해 그 대답을 해준다. 이 layout attribute를 직접 만들어서 사용하는 것이 주 목표이다.


  1. card들의 높이값을 가져오기 위해 card model을 가리킬 수 있는 변수를 선언한다. 나중에 main view에서 이 model을 넘겨주어 공유할 수 있도록 할 것이다.

  2. 개별적인 cell의 위치와 크기를 저장할 attribute 배열

  3. view 내부에서 cell들이 자리할 수 있는 공간을 반환한다. 특별한 경우가 아니라면 collection view와 동일한 영역에 cell들이 들어갈 것이기 때문에 바로 그 크기를 반환해준다.


  1. 원하는 모습은 pinterest 처럼 card가 세로 2줄로 나열되는 것이다. 따라서 각 열에 해당하는 card의 origin y값을 저장하기 위해 크기가 2인 배열을 선언한다.

  2. 각 줄에 cell height 값만큼 origin y값을 업데이트한다.


  1. 현재 보여지는 영역을 전달받는다. 여기서는 해당 영역에 포함되는 즉, 화면에 실제로 보여지는 attribute들만 추려서 반환하도록 했다. scroll 이벤트가 발생하거나 collection view의 크기가 변하는 등의 이벤트가 발생할 때 호출되는 것으로 추정된다.

  2. index path를 전달받는다. 해당하는 attribute를 반환하도록 한다.






결과화면


여기까지 진행하면 그림과 같은 모습을 볼 수 있을 것이다.



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함