Swift應用案例 1.無限輪播

weixin_34075551發表於2017-03-10

從今天開始,我學習的重點開始轉向Swift,並且會分享一些自己學習的心得體會,今天給大家帶來的的是無限輪播。廣告頁的無限輪播是非常常見的一個功能,大多數APP都有,大多數程式設計師也都實現過,今天我們用Swift實現一下。專案地址
  圖片切換我們可以選擇的基本控制元件有兩個UIScrollView 和 UICollectionView,這次我們選擇UICollectionView;既然是輪播,就會用到Timer。所以,我們這次主要應用的知識點為UICollectionView 和 Timer;

import UIKit

class CycleScrollView: UIView, UICollectionViewDelegate,UICollectionViewDataSource {

    var bottomView : UICollectionView?
    var width : CGFloat?
    var height : CGFloat?
    var timer : Timer?
    
    override init(frame: CGRect){
        
        super.init(frame: frame)
        // 1.設定背景色
        self.backgroundColor = UIColor.clear
        // 2.設定寬高
        width = self.frame.size.width
        height = self.frame.size.height
        // 3.新增bottomView
        setupBottomView()
        // 4.新增定時器
        setupTimer()
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    func setupBottomView() {
        
        // 5.設定collectionView的佈局
        let flowLayout = UICollectionViewFlowLayout();
        flowLayout.itemSize = self.bounds.size
        flowLayout.minimumLineSpacing = 0;
        flowLayout.minimumInteritemSpacing = 0;
        flowLayout.scrollDirection = UICollectionViewScrollDirection.horizontal;
        bottomView = UICollectionView.init(frame: self.bounds, collectionViewLayout: flowLayout)
        self.addSubview(bottomView!);
        // 6.設定collectionView的尺寸
        bottomView?.contentSize = CGSize(width:width! * CGFloat(4),height:height!)
        // 7.分頁
        bottomView?.isPagingEnabled = true
        // 8.去掉滾動條
        bottomView?.showsVerticalScrollIndicator = false
        bottomView?.showsHorizontalScrollIndicator = false
        // 9.設定代理
        bottomView?.delegate = self
        bottomView?.dataSource = self
        // 10.註冊cell
        bottomView?.register(UICollectionViewCell().classForCoder, forCellWithReuseIdentifier: "ID");
        if #available(iOS 10.0, *) {
            // 11.預載入
            bottomView?.isPrefetchingEnabled = true
        } else {
            // Fallback on earlier versions
        }
    }
    func setupTimer() {
        // 12.例項化定時器
        timer = Timer.init(timeInterval: 2, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true);
        RunLoop.main.add(timer!, forMode: RunLoopMode.defaultRunLoopMode);

        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
        
            self.timer?.fire();
        }
    }
    func timerAction() {
        
        var contentOffsetX = (self.bottomView?.contentOffset.x)! + self.frame.size.width
        
        if contentOffsetX > self.frame.size.width * 3  {
            // 當前檢視顯示的是第三個的時候,設定bottomView的偏移量為0
            self.bottomView?.contentOffset = CGPoint(x:0,y:0)
            contentOffsetX = self.frame.size.width
        }
         self.bottomView?.setContentOffset(CGPoint(x:contentOffsetX,y:0), animated: true)
    }
    // 重寫removeFromSuperview方法,用於刪除定時器,否則定時器一直存在,浪費記憶體
    override func removeFromSuperview() {
        
        timer?.invalidate()
        timer = nil
        super.removeFromSuperview()
    }
    // Mark:UICollectionViewDataSource
    // 設定Itmes
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        
        return 4;
    }
    // 設定cell
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell : UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ID", for: indexPath)
        for view : UIView in cell.contentView.subviews {
            
            view.removeFromSuperview()
        }
        let imageView = UIImageView.init(frame: cell.contentView.bounds)
        if indexPath.row < 3 {
            
            imageView.image = UIImage.init(named: String(indexPath.row))

        } else {
           imageView.image = UIImage.init(named: String(0))
        }
        cell.contentView.addSubview(imageView)
        
        return cell;
    }
    // Mark:UICollectionViewDelegate
    // 點選方法
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        
        print("您點選了第 \(indexPath.row == 3 ? 0 : indexPath.row) 個");
    }
    
}

UICollectionView 和 Timer的用法和OC基本相同。Swift和OC的UI部分應該是一致的,因為底層都是OpenGL。我直接說一下區別:
1.Timer:如果重複,OC是等一個間隔再執行的,Swift是立即執行的,所以我用了GCD延時開啟定時器。
2.Swift 沒有 CGPointZero。
  無限輪播的原理就是在最後面多新增一個和第一個相同的itme。當你滑動到最後一個itme時,把UICollectionView的contentOffset置零,繼續向右活動。如果不新增,會給使用者一種卡頓的感覺。

相關文章