728x90
UICollectionView로 자동 Paging 배너 만들기
안드로이드에서는 다음과 같은 Paging 배너 효과를 구현하기 위해선 ViewPager를 활용해야 한다. ios에서는 ViewPager처럼 Paging에만 특화된 뷰는 PagingViewController가 있는데 이건 커스텀이 힘들어 보이고 대부분 CollectionView의 범용성을 활용한다.
Paging 배너 구현
- section의 개수는 1개로 지정한다.
- cell의 크기를 CollectionView와 동일하게 맞춰준다.
- cell사이와 section사이의 여백을 없앤다.
여기까지 하게 된다면 수동으로 스크롤이 가능한 배너가 만들어진다. 추가적으로 여기에 마치 배달의 민족 같은 앱에서 볼 수 있는 자동 스크롤 기능까지 넣고자 한다면 아래와 같이 하면 된다.
자동 스크롤링 기능
- DispatchQueue를 이용해서 비동기적으로 무한 루프 안에 주기적으로 collectionView.scrollToItem() 메서드를 호출한다.
- UIScrollViewDelegate를 채택 후 scrollViewDidEndDecelerating 메서드를 구현해서 사람이 직접 스크롤을 했을 때 현재 scroll 된 page의 index를 인식할 수 있도록 해준다.
//
// ViewController.swift
// Practice
//
// Created by jupark136 on 2020/12/14.
//
import UIKit
import Alamofire
class ViewController: UIViewController {
var currentPage: Int = 0
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
collectionView.decelerationRate = .fast
collectionView.dataSource = self
collectionView.delegate = self
collectionView.isPagingEnabled = true
startAutoScroll()
}
func startAutoScroll() {
//전체 cell 개수
let totalCellCount = collectionView.numberOfItems(inSection: 0)
DispatchQueue.global(qos: .default).async {
while true
{
//2초에 한 번씩 paging
sleep(2)
DispatchQueue.main.async {
self.collectionView.scrollToItem(at: IndexPath(item: self.currentPage, section: 0), at: .right, animated: true)
//다시 처음으로
if self.currentPage == totalCellCount - 1 {
self.currentPage = 0
}
else {
self.currentPage += 1
}
}
}
}
}
}
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
//총 page 개수
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
3
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "\(TestCell.self)", for: indexPath) as? TestCell else {
fatalError("cell not")
}
cell.label.text = "\(indexPath.row)"
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int
{
1
}
//cell과 collectionview의 크기를 일치
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
CGSize.init(width: collectionView.bounds.width, height: collectionView.bounds.height)
}
//section 내부 cell간의 공간을 제거
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
0
}
//section 사이의 공간을 제거
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
0
}
}
extension ViewController: UIScrollViewDelegate {
//수동으로 넘을 때 page를 인식
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let x = scrollView.contentOffset.x
let w = scrollView.bounds.size.width
currentPage = Int(ceil(x/w))
print(currentPage)
}
}
728x90
'iOS > 설명' 카테고리의 다른 글
[iOS] UIViewController Life Cycle (생명주기) (0) | 2021.01.20 |
---|---|
[iOS] UILabel의 text를 top-left 정렬하기 (0) | 2021.01.14 |
[iOS] 안전 영역 (Safe Area) (0) | 2020.12.21 |
[iOS] 오토 레이아웃 (Auto Layout) (0) | 2020.12.21 |
[iOS] View Controller 뷰 컨트롤러 (0) | 2020.12.18 |
댓글