iOS

iOS) Carousel 구현하기

삼쓰 웅쓰 2019. 5. 12. 13:15
728x90
개인적으로 공부하며 정리하는 블로그 입니다.
오류나 부족한 부분이 있을 수 있으니 감안하고 봐주시고 아낌없는 조언 감사드립니다 ^^

 

오늘은 이런 Carousel 라고 부르는 슬라이드를 만들어 보겠습니다.

제가 사용할 방법은

 

\

 

CollectionView를 Horizontal 방향으로 돌려서 구현하는 방식입니다.

 

\

 

사실상 CollectionView Tutorial에 가깝다고 볼 수 있겠습니다 XD

 


 

자 그럼 먼저 collectionView를 한번 만들어 볼텐데요,

tableView 처럼 별다른 설정 없이 생성한다면?

let collectionView = UICollectionView()

'UICollectionView must be initialized with a non-nil layout parameter' 라는 에러를 만나실 수 있습니다..

네 보시다시피 collectionView는 tableView와는 달리 한 가지 주의할 점이 있는데요 

layout없이 초기화 할 수 없습니다!!

 

이제 알았으니 layout을 주고 제대로 생성해볼까요? 

어차피 contraints를 또 걸어줄거기 때문에 위치는 대충 잡고 잘 보이게 빨간색을 줘보겠습니다

let carouselCollectionView: UICollectionView = {
        
    let flowLayout = UICollectionViewFlowLayout()
    let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 100, height: 100), collectionViewLayout: flowLayout)
    collectionView.translatesAutoresizingMaskIntoConstraints = false
    collectionView.backgroundColor = UIColor.red

    return collectionView
}()

네 우선 생성은 잘 됐네요!

 

ViewDidLoad() 에 다음과 같이 contraint를 주도록할게요!

NSLayoutConstraint.activate([
    carouselCollectionView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0),
    carouselCollectionView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0),
    carouselCollectionView.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor),
    carouselCollectionView.heightAnchor.constraint(equalToConstant: 300)

    ])

위치를 센터로 옮기고

높이는 적당히, 너비는 스크린 화면만큼 채워볼게요!

 

잘 만들어진 걸 확인했으니, 이제 cell을 만들어야겠죠?

tableView 처럼 collectionView도 Datasource 를 상속 받으면

필수로 구현해줘야 하는 녀석들이 있어요 

테이블 뷰와 거의 비슷하답니다!

 

cell은 잘보이게 파란색으로 또 한번 줘볼게요.

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 5
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        cell.backgroundColor = UIColor.blue
        return cell
    }
}

extension ViewController: UICollectionViewDelegate {
    
}

 

이제 carouselCollectionView에 등록도 해볼게요

carouselCollectionView.dataSource = self
carouselCollectionView.delegate = self
carouselCollectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
        

그럼이제 cell도 잘 생성이 됐습니다!

 

그럼 이제 본격적으로 Carousel 을 구현해봐야 할텐데요, 

맨 처음에 말씀드렸다시피 collectionView의 scroll 방향을  horizontal로 바꿔서 구현해볼거에요. 

 

자 그럼 여기서 질문!

collectionView의 기본 scroll 방향은 뭘까요?

 

네 맞습니다 collectionView는 기본적으로

Vertical 로 되어있어요!

 

근데 vertical은 수직인데 왜 셀들은 가로 방향으로 생기지..? 

라고 혹시 생각하신분들이 계실거에요!

(네 접니다....)

 

여기서 scrollDirection에 주의를 하셔야 하는데요, 

이렇게 셀이 가로로 생성이되어야 그 다음 section은 아래줄에 생겨서 Vertical로 스크롤 할 수 있겠죠?

마찬가지 원리로 horizontal로 한다면?

네 cell은 수직으로 생기게 됩니다 !!

 

collectionView의 scrollDirection은 처음에

반드시 만들어서 넣어야 했던

layout

에서 설정해줄 수 있습니다!

let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
        

 

말씀드렸던대로 셀이 수직 방향으로 잘 생성이 되는 것을 확인할 수 있습니다!

 

이제 셀의 높이를 collectionView만큼 주면 세로로 스크롤이 되겠죠??

셀의 사이즈를 변경해 주기 위해선 UICollectionViewDelegateFlowLayout 을 상속받아 구현해야 합니다!

extension CarouselViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        // code
    }
}

눈이 너무 아프죠? 죄송합니다..

이제 CollectionView의 배경을 clear시키고 셀은 흰색, ViewController의 배경을 조금 바꿔볼게요

그리고 셀의 크기를 키워볼게요

return CGSize(width: view.frame.width - 80, height: view.frame.height)

짠!

네.. 되긴 됐는데.... 최선인가 싶으시죠? 

조금 고쳐보겠습니다!

 

우선 셀 사이의 간격을 띄워볼게요!

scorllDirection과 마찬가지로 CollectionView의 Layout을 고쳐주면 된답니다!

flowLayout.minimumLineSpacing = 20

다음은 전체적인 좌우 간격을 띄워볼게요!

flowLayout.sectionInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)

 

 

네 완성되었습니다 :D

 

배경을, 그리고 카드를 좀 더 예쁘게 만들어보고 싶으시다면

다음 글 을 참고해주세요!!