공부한 것
정리
- 컬렉션 뷰는, 관련이 있는 여러 가지 데이터를 유연한 레이아웃을 통해 시각적으로 표현하기 위해 사용한다.
- 보통 격자 형태를 많이 활용한다.
- 하지만, 언제나 그렇듯 Subclassing을 통해 다양한 응용이 가능하다. 격자, 스택, 원형, 심지어 다이나믹하게 변하는 데이터 배치 레이아웃도 가능하다고?!
- 컬렉션 뷰를 이루고 있는 오브젝트는 다음과 같다 : 셀, 레이아웃, 데이터 소스 오브젝트, 델레게잇 오브젝트, 컬렉션 뷰 컨트롤러.
- 셀은 각각의 컨텐츠 "조각"에 대한 시각적 표현을 제공한다.
- 레이아웃은 이 셀들을 시각적으로 어떻게 배열하느냐를 정의한다.
- 데이터 소스 오브젝트는 테이블 뷰 때처럼, 프로토콜 형태로 제공되며 컬렉션 뷰에 데이터를 제공한다.
- 델레게잇 오브젝트도 마찬가지. 유저와의 상호작용에 따른 액션을 어떻게 할 지 정한다.
- 컬렉션 뷰에서 할 수 있는 몇몇 기능을 사용하기 위해서는, 컬렉션 뷰 컨트롤러를 쓰는 것이 좋다.
- 애플 휴먼 인터페이스 가이드라인에 따르면, 컬렉션 뷰는 이미지를 기반으로 한 무언가를 표시할 때 가장 적합하다.
- 가능한 표준에 가까운 격자 형태나, 행 형태로 만들어야 한다. 보통 컬렉션은 가로 행 형태로 컨텐츠를 배치한다. 이것이 사용자가 느끼기에 익숙하고 편하기 때문! 사용자를 혼란스럽게 할 커스텀 레이아웃은 피하는 게 좋다고 보여진다.
- 텍스트로 이루어진 컬렉션 뷰를 쓸거면, 차라리 테이블 뷰를 쓰는 걸 생각해보자. 보통은 이렇게 하는 것이 만들기도 더 쉽고 사용자가 이해하기도 더 쉽다.
- 각각의 아이템은 선택하기 쉽게 해 두는게 좋다. 만약 컬렉션 안에 있는 개별 아이템에 도달하기가 너무 어렵다면, 사용자들은 당황하고 이내 흥미를 잃게 될 것이니까.. 적절히 패딩을 두는 게 좋을 수 있겠다. 컨텐츠가 겹치는 것도 막고, 아이템에 온전히 집중할 수 있기 때문.
- 필요하다면 상호작용에 따른 커스텀 액션을 더해 주자. 기본적으로는 탭했을때, 편집을 위해 꾹 누르고 있을 때, 스와이프를 통해 스크롤할 때 등의 경우가 있겠다. 커스텀 액션이 필요하다면 만들어 줌으로써 상호 작용을 강화할 수 있다.
- 사람들이 삽입, 수정, 삭제할 때 그게 잘 되고 있다고 표시하기 위해 애니메이션을 활용하자. 컬렉션 뷰는 이러한 액션들을 위한 기본 애니메이션을 제공한다구~
- 다이나믹 레이아웃 체인지를 할 때는 각별히 주의해주자. 컬렉션의 레이아웃은 다이나믹하게 바뀔 수 있어서, 이게 오히려 조심해야 할 점이 되기도 한다. 유저가 앱을 사용하고 있는데, 유저와의 상호작용에 따른 결과가 아닌데도 레이아웃이 휙 바뀌면 혼란스러울 테니까.
- 컬렉션 뷰를 관장하는 클래스는 당연하겠지만
UICollectionView
.
- 컬렉션 뷰를 앱에서 쓴다는 건, 해당 컬렉션 뷰와 관련된 데이터를 관리하는 것이 또한 그 앱이 해야 할 일임을 나타내는 것이기도 하다.
dataSource
프로퍼티에서 필요한 데이터를 가져 온다.
- 여기에 간단하게 데이터를 더하려면
UICollectionViewDiffableDataSource
를 사용하면 된다.
- 커스텀 데이터 소스 오브젝트를 만들고 싶다면,
UICollectionViewDataSource
를 사용한다.
- 컬렉션 뷰 안의 개개의 아이템들은, 또한 섹션으로 분리할 수도 있다. 아이템은 컬렉션 뷰에서 가장 작은 하나의 단위. 예를 들면 사진 앱의 한 개의 사진 정도?
UICollectionViewCell
로 구현할 수 있겠지?
- 컬렉션 뷰에서 데이터를 표현할 때 셀만 쓸 수 있는 것은 아니다! 섹션 헤더나 푸터 같은 걸로도 대략의 정보를 표시할 수 있다.
- 컬렉션 뷰에서 데이터를 표시하고자 하는 순서가 있을 것이다.
UICollectionViewDiffableDataSource
는 이를 자동으로 관리해 준다. 만약 UICollectionViewDataSource
를 사용한 커스텀 데이터 소스 오브젝트를 사용한다면, 삽입과 수정 그리고 삭제에 대한 메서드를 사용해 셀의 위치를 관리한다.
- 레이아웃은
UICollectionViewLayout
클래스로 관리한다. 말하자면 데이터 소스랑 비슷한데, 데이터가 아니라 레이아웃 정보를 들고 있는 것.
- 보통 컬렉션 뷰를 만들 때 정하지만, 다이나믹하게 바꿔줄 수도 있다.
collectionViewLayout
프로퍼티를 바꿔 줌으로써 바꿀 수 있다. 다만 이건 즉시 바뀌는 것.
- 애니메이션과 함께 바꾸고 싶다면
setCollectionViewLayout(_:animated:completion:)
메서드를 활용해 보자.
startInteractiveTransition(to:completion:)
, finishInteractiveTransition()
, cancelInteractiveTransition()
등을 통해 제스처나, 터치 이벤트에 따른 레이아웃의 전환을 구현할 수 있다. 스타트 메서드가 일종의 '중간 레이아웃'을 만들고 변화 과정을 추적하며, 피니시나 캔슬을 통해 이를 없애고 레이아웃의 변화를 적용한다.
- cell과 supplementary view가 있고, dequeue reusable ~~ 가 가능하다구!
- 전자는
UICollectionViewCell
, 후자는 UICollectionReusableView
를 반환한다.
- 프리-페칭에 관련된 두 가지 수단을 가지고 있다. 이건 제법 중대사라고 할 만 하다..
- 셀 프리페칭은 기본적으로 활성화되어 있다. 셀이 필요한 시점 이전에! 셀을 미리 준비해두는 것을 말한다. 많은 수의 셀이 필요할 경우, 셀 프리페칭을 활용해 여러 스레드에 셀을 불러오는 작업을 나누어 준다.
- 데이터 프리페칭은 셀이 준비되기 전에 데이터가 필요할 때 알 수 있게 해주는 역할을 한다. 셀에 들어가는 데이터가 무거운 종류의 데이터일 때 유용하다.
UICollectionViewDataSourcePrefetching
프로토콜을 채택하는 오브젝트의 prefetchDataSource
프로퍼티를 통해 이 시점에 알림을 받을 수 있다.
- 컬렉션 뷰의 아이템들의 정렬은 기본적으로 자동으로 정해지지만, 유저와의 상호작용을 통해 바뀔 수 있고, Gesture Recognizer 설정을 통해 이를 추적하고, 그에 따라 아이템의 정렬된 순서를 갱신할 수 있다.
beginInteractiveMovementForItem(at:)
를 통해 추적을 시작한다.
updateInteractiveMovementTargetPosition(_:)
을 통해, 유저와 상호작용하고 있는 중에도 실시간으로 터치 위치 등의 변경을 반영한다.
endInteractiveMovement()
또는 cancelInteractiveMovement()
를 통해 이를 종료한다.
- 유저와 상호작용하고 있는 중에, 컬렉션 뷰는 레이아웃을 다이나믹하게 "무효화시키고", 아이템의 현재 위치를 반영한다.
- 기본적으로는 유저의 상호작용에 따라 그냥 재배열을 해 주지만, 애니메이션도 넣을 수 있다.
- 상호작용이 끝나면, 컬렉션 뷰는 새 위치에 대응하게끔 데이터 소스를 업데이트한다.
고민한 점 및 생각해본 점
- 프리페칭과 유저와의 상호작용, 이 두 가지가 중요하다고 느껴졌다.
- 애플은 컬렉션 뷰를 이미지 위주의 데이터를 표시할 때 쓸 것을 권장한다. 그렇다면, 당연히 개개의 셀에 들어가는 데이터를 로드하는 시간은 더 걸릴 것이다. 이를 위해 미리 서버로부터 데이터를 받아온다는 것이 좋은 아이디어라고 생각했다.
- 레이아웃이 자유로우니만큼, 활성화했을 때 유저가 그 순서를 재배열할 때도 테이블 뷰에 비해 신경쓸 것이 많다고 느꼈다. 이전에 배운 Gesture Recognizer와 잘 조합해 쓸 수 있어야겠다.
- 이외에도, 솔직히 내용이 많아서 한 번 본다고 이해할 수 있을진 모르겠는데, 그래도 한 번 읽고 내 무의식에 조금 흔적을 남겨둔 다음, 자주 쓰면서 연습해 보면 잘 쓸 수 있게 되지 않을까..
참조
https://developer.apple.com/documentation/uikit/uicollectionview
https://developer.apple.com/design/human-interface-guidelines/components/layout-and-organization/collections/
https://developer.apple.com/documentation/uikit/views_and_controls/collection_views