본문 바로가기

IOS

Swift - UICollectionView + Paging

CollectionView 에 Paging 기능을 추가해서

이미지 관련 배너 및 썸네일을 만들때 유용하게 사용 할수 있다.

좀더 간단하게 만들기 위해 RxSwift, RxCocoa를 이용했다

 

1. ViewController

import UIKit
import RxCocoa
import RxSwift

class ViewController: UIViewController {

    @IBOutlet weak var mCollectionView: UICollectionView!
    @IBOutlet weak var mCountText: UILabel!
    
    var imageArray = ["image1", "image2", "image3", "image4"]
    
    let lineSpacing: CGFloat = 20

    let cellRatio: CGFloat = 0.8
    var previousOffset: CGFloat = 0
    var currentPage: Int = 0
    
    var disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        initSetting()
        initRx()
    }
    
    func initSetting() {
        
       let cellWidth = floor(view.frame.width * cellRatio)
       let cellHeight = floor(mCollectionView.frame.height * cellRatio)
        
       let layout = mCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
       layout.itemSize = CGSize(width: cellWidth, height: cellHeight)
       layout.minimumLineSpacing = lineSpacing
       layout.scrollDirection = .horizontal
     
       mCollectionView.decelerationRate = UIScrollView.DecelerationRate.fast
       
       mCollectionView.register(UINib(nibName: "ImageItem", bundle: nil), forCellWithReuseIdentifier: "ImageItem")
       mCollectionView.rx.setDelegate(self).disposed(by: disposeBag)
    }
    
    func initRx() {
        
        Observable.of(imageArray)
        .asObservable()
        .bind(to: mCollectionView.rx.items(cellIdentifier: "ImageItem", cellType: ImageItem.self)) {
            index, item, cell in
            
            cell.mImageView.image = UIImage(named: item)
            
        }.disposed(by: disposeBag)
        
    }
}

2. Extension - UIScrollViewDelegate(Paging)

extension ViewController : UIScrollViewDelegate {
    
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let point = self.targetContentOffset(scrollView, withVelocity: velocity)
        targetContentOffset.pointee = point
        
        UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: velocity.x, options: .allowUserInteraction, animations: {
            self.mCollectionView.setContentOffset(point, animated: true)
        }, completion: nil)
    }
    
    func targetContentOffset(_ scrollView: UIScrollView, withVelocity velocity: CGPoint) -> CGPoint {
        
        guard let flowLayout = mCollectionView.collectionViewLayout as? UICollectionViewFlowLayout else { return .zero }
        
        if previousOffset > mCollectionView.contentOffset.x && velocity.x < 0 {
            currentPage = currentPage - 1
        } else if previousOffset < mCollectionView.contentOffset.x && velocity.x > 0 {
            currentPage = currentPage + 1
        }
        
        let additional = (flowLayout.itemSize.width + flowLayout.minimumLineSpacing) - flowLayout.headerReferenceSize.width
        
        let updatedOffset = (flowLayout.itemSize.width + flowLayout.minimumLineSpacing) * CGFloat(currentPage) - additional
        
        previousOffset = updatedOffset
        
        mCountText.text = "이미지 카운트 : \(currentPage)"
    
        return CGPoint(x: updatedOffset, y: 0)
    }
}

3. 실행결과

카운트가 뭔가 이상한데?????


4. 카운트 처리 수정

스크롤시에 카운팅 하는부분에대해 다음과 같이 조건을 추가해줍니다.

 if previousOffset > mCollectionView.contentOffset.x && velocity.x < 0 {
   currentPage = currentPage - 1
   if currentPage == 0 || currentPage == -1 {
   	currentPage = 1
   }
 } else if previousOffset < mCollectionView.contentOffset.x && velocity.x > 0 {
   currentPage = currentPage + 1
   if currentPage > imageArray.count {
   	currentPage = imageArray.count
   }
 }

5. 실행결과

오늘도 감사합니다 아이유님

 

참고 : https://github.com/taewoojin/CollectionViewPagingExample

 

taewoojin/CollectionViewPagingExample

example for collectionView Paging. Contribute to taewoojin/CollectionViewPagingExample development by creating an account on GitHub.

github.com

https://eunjin3786.tistory.com/203 

 

[UICollectionView] Paging / Carousel / Snap Collectionview with header, footer

이 글의 목적은 header, footer가 있는 collectionview를 Paging 또는 Carousel 또는 Snap 하기--!! 인데요, 점진적으로(??) 설명하겠습니다. [1] cell 간 spacing이 없는 CollectionView (화면 사이즈와  cell..

eunjin3786.tistory.com

 

'IOS' 카테고리의 다른 글

Swift - ReactorKit / ErrorHandling  (0) 2021.07.24
Swift - iOS 면접 질문 리스트  (0) 2021.07.18
Swift - SceneDelegate  (0) 2021.07.10
Swift - ReactorKit2  (0) 2021.07.06
Swift - ReactorKit  (0) 2021.06.09