본문 바로가기
개린이 이야기

Infinite Carousel 구현

by iOS 개린이 2023. 1. 21.

 

위 사진처럼 무한히 보여주는 Carousel을 구현하는 방법에 대해서 설명해보려고 한다.

이것을 구현하기 위해 너무도 많은 Carousel 관련 블로그를 보았다.(머리가 그만큼 안좋음.)

다른 블로그들에는 쉽다고 하는데.. 왜 나는 하루종일 걸렸을까... 

 

 

Carousel

-컨베이어 벨트처럼 이어지는 뷰를 말한다.

-어느 방향으로 스크롤하든 무한으로 이어질 수 있다.

-포커스되어 있는 cell이 아니라면 크기를 작게. 

-타이머를 이용하여 자동으로 스크롤.

-스크롤에 맞춰 pagecontrol의 currentpage 변경

 

 

1. CollectionView 설정 

 

중요한 것만 말해보면

1) 컬렉션 뷰 안의 inset을 설정해주는 것으로, cell을 가운데에 위치시키기 위해 left, right 각 inset을 넣어주세요.

-스크롤을 통해 페이지를 넘길 때 cell을 center에서 스크롤해주기 때문에 간격을 맞춰놓아야 함.

 

2) 컬렉션 뷰의 decelerationRate = .fast,  isPaging = false 설정해주세요. 

-그냥 스크롤하면 휘리리리릭가버림. 이걸 쓰면 페이징 다워짐.

 

 

2. CollectionView DataSource

 

-결국 유저에게 보여주는 이미지는 5개이다.

일단 cell의 시작은 가운데에서 하게 될 것이다. 그리고 양 방향 어디로든지 cell을 넘기다가 끝 무렵이 오면 다시 가운데로 되돌아오도록 만들 것임.

 

 

3. Cell 시작을 가운데로

 

-cell을 가운데부터 시작해야 유저가 끝을 모르겠죠?

-왜 viewDidLayoutSubviews 메소드에 적냐? CollectionView와 Cell이 모두 그려지고 난 후에 index를 옮겨줘야 해서

 

 

4. Paging effect

-스크롤 하면 딱 원하는 위치에 멈추도록, 스크롤을 약하게 하면 못 넘기도록 페이징 효과를 나타내게 한다.

 

 

-scrollViewWillEndDragging 은 스크롤뷰의 드래그가 끝나려고 할 때 실행되는 메소드이다.

UIScrollView의 delegate에 있는 메소드인데, UICollectionview가 UIScrollView를 채택하고 있어서 사용이 가능하다.

 

-유저가 스크롤을 완료할 때 어느 방향으로 스크롤을 했는지, 그 속도는 페이지를 넘길만한 것인지, 현재 위치, cellsize만큼 넘겨주면 페이징 효과 구현 완료.

 

 

5. Infinite effect

-무한으로 돌아가는 Carousel을 위한 코드

-페이징을 위해 사용했던 메소드 scrollViewWillEndDragging와 scrollViewDidEndDecelerating 메소드 두 가지를 사용한다.

 

-먼저 두 가지 변수를 선언해줌.

 

 

 

-beginOffset은 유저가 왼쪽으로 스크롤을 해서 cell이 특정 위치까지 도달했을 때 다시 중간 index로 보내주기 위해서

그 특정 위치를 선언해준 것이다. (0번에서 왼쪽으로 스크롤하면 4번이 보여야겠죠? 그 0번에서 스크롤했을 때 위치입니다.)

 

endOffset도 마찬가지로 유저가 오른쪽으로 스크롤해서 마지막에 도달하려고 할 때 다시 중간 index로 보내주기 위해서 특정 위치를 선언해준 것. 

 

-유저가 스크롤 했을 때 스크롤된 위치 좌표가 지정해준 특정 위치(beginOffset)를 넘기고 && 스크롤해줄만한 속도라면

index가 되돌아간다. (되돌아가는 코드는 아래 구현.)

 

 

 

-scrollViewDidEndDecelerating은 유저가 스크롤을 하면 스크롤 애니메이션이 실행되는데, 이 애니메이션들이 모두 완료되면 실행되는 메소드이다.

 

-scrollToBegin과 scrollToEnd의 state를 받아서 중간으로 되돌려줄 때라면 스크롤을 해준다.

보여줘야 하는 cell이 0번~4번이기 때문에 0번에서 왼쪽으로 스크롤하면, 4번을 보여주도록 하고

4번에서 오른쪽으로 스크롤하면, 0번을 보여주도록 한다.

 

 

6. cell 크기 조정 animation

-포커스 된 cell은 크기를 크게 만들어주고, 나머지 cell들은 다시 작게 만들어줘야한다.

 

 

-우리는 가장 첫 번째로 보여주는 cell의 Index가 20이기 때문에 저렇게 하나 선언해줌.

 

 

 

-현재 보여주는 cell말고 나머지 cell들은 모두 크기 작게 해줌.

 

 

 

 

-포커스된 셀을 크게 해주는, 포커스가 풀린 셀을 다시 작게 해주는 애니메이션 메소드

 

 

-위에서 봤던 코드들과 비슷합니다.

1) 셀 사이즈와 컬렉션뷰 안에서 현재 위치를 통해서 지금 보여지는 셀의 인덱스가 몇 번인지 알아낸다.

2) 인덱스에 맞는 셀에 커지는 애니메이션 부여

3) 넘겨진 셀은 다시 작아지도록 애니메이션 부여

4) previousCellIndex를 현재 인덱스로 변경

 

 

 

7.  Timer를 통해 자동 스크롤 구현

 

-세가지 변수 선언

currentIndex는 타이머를 통해 다음 셀로 넘겨주기 위해

pageIndex는 pagecontrol을 위해(설명은 8번에서)

 

 

 

-3초마다 moveToNextCell을 해줌.

 

 

-3초마다 다음 셀로 넘겨주다가, 특정 인덱스에 도착하면 다시 처음 보여준 셀로 되돌려준다.

 

 

8.  PageControl 구현

 

 

-페이지 컨트롤 기본 설정해줌.

 

 

 

1) 컬렉션뷰의 현재 x위치를 270(셀 사이즈 + 셀 간격)으로 나누면 현재 인덱스가 몇 번인지 나옴.

 

2) pageIndex를 5로 나눈 나머지를 currentPage로 만들어줌. 

페이지 컨트롤로 보여주는 페이지는 5개인데, 현재 페이지는 0~4로 표현이 되지 않는 인덱스임.(20번, 21번 이런식)

그래서 5로 나눈 나머지를 보여주는 것임.

 

3) 타이머로 3초마다 스크롤이 되는데 그것과 맞춰 currentIndex를 변경해주어야 함.

 

4) 이것을 scrollViewDidScroll 메소드 안에 넣어주셈.

 

 

 

-여기에도 pageIndex를 넘겨주는 코드 추가해주셈.

 

구현완료.

 

 

'개린이 이야기' 카테고리의 다른 글

디자인 패턴 - MVC 패턴에 관하여  (0) 2023.04.04
SingleTon(싱글톤)에 관하여  (0) 2023.02.03
Custom Splash 화면  (0) 2023.01.17
Google AdMob(애드몹)에 관하여  (0) 2023.01.15
With Calendar 프로젝트를 하면서  (0) 2023.01.09