Carousel Using UICollectionView

Jongwon Woo
4 min readDec 12, 2020

--

UICollectionView로 Carousel UI를 만들었습니다.

핵심

  • 셀을 아이템 수보다 2개 더 만들어서
  • > 첫 번째 아이템의 왼쪽에는 마지막 아이템의 복제 셀을,
  • > 마지막 아이템의 오른쪽에는 첫 번째 아이템의 복제 셀을 표시합니다.
  • 첫 번째 아이템에서 오른쪽을 스와이프하면 마지막 아이템의 복제 셀을 보여준 후 마지막 아이템의 진짜 셀로 애니메이션없이 이동시킵니다.
  • 마지막 아이템에서 왼쪽으로 스와이프하면 첫 번째 아이템의 복제 셀을 보여준 후 첫 번째 아이템의 진짜 셀로 애니메이션없이 이동시킵니다.

if indexPath.item == cellIndexOfLastItem {
….if let rightCell = collectionView.cellForItem(at: IndexPath(item: cellIndexOfLastItem+1, section: 0)), collectionView.bounds.contains(collectionView.convert(rightCell.center, to: collectionView)) {
……..let xOfCellOfFirstItem = cell.frame.width
….….collectionView.contentOffset = CGPoint(x: xOfCellOfFirstItem, y: 0)
.…}
}

Fine Tuning

  • 스와이프를 매우 빠르게 계속 하면 양끝에서 연결이 끊어지는 경우가 생깁니다. 복제 셀에서 진짜 셀로 이동할 때 scrollTo 메소드를 사용할 때 그렇습니다. contentOffset에 값을 직접 넣는 경우에는 그렇지 않습니다.
  • 양 끝에서 스와이프를 힘차게 하면 연결된 셀이 가운데에서 멈추지 않는 경우가 생깁니다. 스크롤이 멈추면 위치를 보정해주면 괜찮아집니다.

let collectionViewCenter = collectionView.center
let cellCenter = collectionView.convert(cell.center, to: collectionView.superview)
let offsetX = collectionViewCenter.x — cellCenter.x
if offsetX != 0 {
collectionView.contentOffset = CGPoint(x: collectionView.contentOffset.x — offsetX, y: collectionView.contentOffset.y)
}

장점

  • 이미 UICollectionView를 이용해서 페이지 처리를 하고 있다면 간단한 수정으로 Carousel을 만들 수 있습니다.

단점

  • UICollectionView가 지원하지 않는 기능을 만들다 보니 양끝을 연결하는 동작이 매끄럽지 않아서 튜닝도 해야 하고,
  • 실제 아이템은 N개인데 셀은 N+2개라서 이를 보정해줘야 합니다.

let item = items[itemIndex(withCellIndex: indexPath.item)]

대안

Infinite Loop View

--

--