轮播图的实现

1、轮播图的协议

protocol SMCarouselViewDelegate: NSObjectProtocol {
   func mCarouselView(_ carouselView: SMCarouselView, didSelectItemAt index: Int);
}

2、轮播视图:SMCarouselView

class SMCarouselView: UIView {
    
    private lazy var layout: UICollectionViewFlowLayout = {
        let layout = UICollectionViewFlowLayout()
        layout.minimumInteritemSpacing = 0
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = 0
        layout.sectionInset = UIEdgeInsets(top: 0, left: 0 , bottom: 0, right: 0)
        return layout
    }()
    
    private lazy var collectionView: UICollectionView = {
        let collection = UICollectionView(frame: .zero, collectionViewLayout: self.layout)
        collection.backgroundColor = UIColor.white
        collection.delegate = self
        collection.dataSource = self
        collection.isPagingEnabled = true
        collection.bounces = false
        collection.showsHorizontalScrollIndicator = false
        collection.register(SMCarouselCell.self, forCellWithReuseIdentifier: "SMCarouselCell")
        return collection
    }()
    
    private lazy var pageControl: SMPageControl = {
        let pageControl = SMPageControl()
        pageControl.contentHorizontalAlignment = .right
        pageControl.isUserInteractionEnabled = false
        let currentPageImg = UIImage.imageWithColor(UIColor(hex: "1F59EE")!,size: CGSize(width: 14, height: 4))
        let pageImg = UIImage.imageWithColor(UIColor.white.withAlphaComponent(0.5),size: CGSize(width: 4, height: 4))
        pageControl.currentPageIndicatorTintColor = UIColor(r: 33, g: 89, b: 237)
        pageControl.pageIndicatorTintColor = UIColor(r: 216, g: 216, b: 216)
        pageControl.currentPage = 0
        return pageControl
    }()
    
    private var timer: Timer? = nil
    private var isAutoScroll: Bool = false
    private var dataArray = [Any]()
    private var maxCount = 0
    
    weak var mCarouselViewDelegate: SMCarouselViewDelegate?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.addSubview(self.collectionView)
        self.addSubview(self.pageControl)
        setTimer()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        Log.info(text: "销毁了???")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        self.collectionView.frame = CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height)
        self.pageControl.frame = CGRect(x: 0, y:  self.bounds.size.height - 15, width:  self.bounds.size.width - 8, height: 10)
    }
    
    func setDataArray(dataArray: [Any]) {
        guard dataArray.count > 0 else {
            return
        }
        self.dataArray = dataArray
        maxCount = self.dataArray.count
        isAutoScroll = self.dataArray.count == 1 ? false : true
        if isAutoScroll {
            self.pageControl.numberOfPages = maxCount
        }else {
            removeTimer()
            self.pageControl.numberOfPages = 0
        }
        self.collectionView.reloadData()
    }
    
    private func setTimer() {
        if self.timer == nil {
            let timer = Timer(timeInterval: 2, repeats: true, block: { [weak self] (_) in
                self?.nextPage()
            })
            RunLoop.current.add(timer, forMode: RunLoop.Mode.common)
            self.timer = timer
        }
    }
    
    private func nextPage() {
        let currentIndexPath = collectionView.indexPathsForVisibleItems.last!
        scrollToItem(at: IndexPath(item: currentIndexPath.item, section: 0), at: .left, animated: false)
        var nextItem = currentIndexPath.item + 1
        var section = 0
        if (nextItem == maxCount) {
            nextItem = 0
            section = 1
        }
        let nextIndexPath = IndexPath(item: nextItem, section: section)
        scrollToItem(at: nextIndexPath, at: .left, animated: true)
    }
    
    private func scrollToItem(at indexPath: IndexPath, at scrollPosition: UICollectionView.ScrollPosition, animated: Bool) {
        self.collectionView.scrollToItem(at: indexPath, at: scrollPosition, animated: animated)
    }
    
    private func lastVisibleItemHandle() {
        let currentIndexPath = collectionView.indexPathsForVisibleItems.last!
        scrollToItem(at: IndexPath(item: currentIndexPath.item, section: 0), at: .left, animated: false)
    }
    
    private func removeTimer() {
        self.timer?.invalidate()
        self.timer = nil
    }
    
    private func resumeTimer() {
        setTimer()
    }
     
    private func getCurrentIndex(scrollView: UIScrollView) -> Int {
        let currentIndex = Int((scrollView.contentOffset.x/scrollView.frame.size.width + 0.5)) % maxCount
        return currentIndex
    }
    
}

extension SMCarouselView: UICollectionViewDelegateFlowLayout,UICollectionViewDataSource {
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return isAutoScroll ? 2 : 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return maxCount
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SMCarouselCell", for: indexPath)
        
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: self.bounds.size.width, height: self.bounds.size.height)
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        self.mCarouselViewDelegate?.mCarouselView(self, didSelectItemAt: indexPath.item)
    }
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        if isAutoScroll {
            removeTimer()
            if (maxCount - 1 == getCurrentIndex(scrollView: scrollView)) {
                lastVisibleItemHandle()
            }
        }
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if isAutoScroll {
            resumeTimer()
        }
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if isAutoScroll {
            let currentIndex = getCurrentIndex(scrollView: scrollView)
            self.pageControl.currentPage = currentIndex
        }
    }

}

3、轮播视图的cell

class SMCarouselCell: UICollectionViewCell {
    private let imageView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        imageView.image = UIImage(named: "roleplacehoder")
        self.contentView.addSubview(imageView)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        imageView.frame = self.bounds
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
//    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
//        let view = super.hitTest(point, with: event)
//        if let _ = view as? UICollectionView {
//            return self
//        }
//        return super.hitTest(point, with: event)
//    }

    
}

你可能感兴趣的:(轮播图的实现)