花落√莫相思

62-Swift之轮播图(UICollectionView)

2017-08-14  本文已影响29人  NetWork小贱

一、 前言

在现在App中首页信息展示非常重要,那问题就来了,如何在有限的空间来展示更多的产品信息呢?随着时代的进步,App的开发人员找到了一种能够满足首页信息更多展示的控件--轮播图。在轮播图的实现中多种多样,今天我们介绍一个实现的方法。使用 UICollectionView来实现,同时减少内存资源的消耗。

二、为什么选择 UICollectionView 做组件?

三、本Demo 使用到的知识点如下

四、本 Demo 的实现效果

Untitled.gif

五、关键代码的展示

1> UICollectionView的创建

// TODO: 创建 UICollectionView对象
func createCollectionView(_rect:CGRect) -> Void {
    // 创建对象
    collectionView = UICollectionView.init(frame:CGRect.init(x: 0, y: 0, width: _rect.size.width, height: _rect.size.height), collectionViewLayout:self.createFlowLayout())
    // 设置代理
    collectionView.delegate = self
    collectionView.dataSource = self
    // 隐藏活动标尺
    collectionView.showsHorizontalScrollIndicator = false
    // 设置 UICollectionView 分页滑动
    collectionView.isPagingEnabled = true
    // 注册 cell
    collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId)
    // 初始让 UICollectionView 显示第二个 Item
    collectionView!.scrollToItem(at: IndexPath.init(row: 1, section: 0), at: .centeredHorizontally, animated: true)
    // 进行渲染
    self.addSubview(collectionView)
}

2> 布局对象的创建

// TODO: 创建布局对象
func createFlowLayout() -> UICollectionViewFlowLayout {
    // 创建对象
    let flowLayout = UICollectionViewFlowLayout.init()
    // 设置滑动方向
    flowLayout.scrollDirection = .horizontal
    return flowLayout
}

3> UICollectionView 的代理事件的实现

// MARK: CollectionView的代理事件

// UICollectionView 返回的 Section 的个数,也可以不写该代理。默认为一
func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

// UICollectionView返回的Item个数
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return (self.handDataArray?.count)!
}

// 设置 Item 的大小
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return self.bounds.size
}

// 设置 Item 之间的间隔
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0.0
}

// 创建和设置 UICollectionViewCell
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    // 创建对象
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
    // 防止cell复用产生
    for item in cell.contentView.subviews {
        item.removeFromSuperview()
    }
    // 创建展示对象
    let cellImageView = UIImageView.init(frame: cell.bounds)
    cellImageView.contentMode = .scaleAspectFit
    cellImageView.image = UIImage.init(named: "defaut.png")
    cellImageView.isUserInteractionEnabled = true
    // 加载图像
    let temp = self.handDataArray?[indexPath.row]
    self.asynLoadImage(temp: temp!, imageView: cellImageView,index: indexPath)
    cell.contentView.addSubview(cellImageView)
    // 返回创建对象
    return cell
}

// CollectionView 的 Item 点击事件
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    if self.delegate != nil {
        self.delegate?.didSelecdItem(index: indexPath)
    }
}

4> ShufflingViewDelegate 的代理声明

protocol ShufflingViewDelegate:NSObjectProtocol {
    func didSelecdItem(index:IndexPath) -> Void
}

5> 网络异步加载

// MARK: 异步加载图像
func asynLoadImage(temp:Any,imageView:UIImageView,index:IndexPath) -> Void {
    // 判断对象的类型
    // UIImage 类型
    if temp is UIImage {
        imageView.image = (temp as! UIImage)
        return
    }
    var tempRequest:Any?
    // URL
    if temp is URL {
        tempRequest = temp as! URL
    }
    if temp is String {
         tempRequest = URL.init(string: temp as! String)
    }
    let request = URLRequest.init(url: tempRequest as! URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 30)
    let session = URLSession.shared
    let dataTask = session.dataTask(with: request, completionHandler: {
        (data, response, error) -> Void in
        if error != nil{
            print(error.debugDescription)
        }else{
            //将图片数据赋予UIImage
            let img = UIImage(data:data!)
            imageView.image = img
            self.handDataArray?.replaceObject(at: index.row, with: img as Any)
        }
    }) as URLSessionTask
    //使用resume方法启动任务
    dataTask.resume()

6>可变数组的元素简单操作

// 处理传入的数据
func handlingData(array:NSArray) -> Int {
    // 初始化可变数组
    self.handDataArray = NSMutableArray.init(capacity: 0)
    // 判断是否存在
    if array.count != 0 {
        self.handDataArray = NSMutableArray.init(array: array)
        self.handDataArray?.add(array.firstObject!)
        self.handDataArray?.insert(array.lastObject!, at: 0)
        return array.count
    }
    return 3
}

7> 定时器的创建

// 定时器的创建
func createTimer() -> Void {
     timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true, block: { (timer) in
        // 获取 UICollectionView 的水平偏移
        let horizontalOffsetX =  self.collectionView.contentOffset.x
        // 计算滑动的个数
        var pageIndex = Int(horizontalOffsetX) / Int(self.bounds.width)
        // 判断图像是否是倒数第二个
        if pageIndex  == (self.handDataArray?.count)! - 1 {
            // 让图像滑动到UICollectionView的第二个Item的位置
            self.collectionView!.scrollToItem(at: IndexPath.init(row: 2, section: 0), at: .centeredHorizontally, animated: false)
            pageIndex = 2
        }else if pageIndex == (self.handDataArray?.count)!-2 {
            pageIndex = 1
            self.collectionView!.scrollToItem(at: IndexPath.init(row: ((self.handDataArray?.count)!-1), section: 0), at: .centeredHorizontally, animated: true)
        }else {
            self.collectionView!.scrollToItem(at: IndexPath.init(row: pageIndex+1, section: 0), at: .centeredHorizontally, animated: true)
            pageIndex = pageIndex + 1
        }
        // 设置小白点的显示
        self.pageControl.currentPage = pageIndex - 1
     })
}

8> 小白点的添加

// 小白点的创建
func createPageControl(index:Int) -> Void {
    pageControl = UIPageControl.init(frame: CGRect.init(x: self.bounds.width - 85, y: self.bounds.height - 30, width: 70, height: 20))
    pageControl.numberOfPages = index
    pageControl.currentPageIndicatorTintColor = UIColor.red
    pageControl.pageIndicatorTintColor = UIColor.white
    self.addSubview(pageControl)
}

9> 滑动的效果实现

// CollectionView的滑动事件
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    self.createTimer()
    // 获取 UICollectionView 的水平偏移
    let horizontalOffsetX =  scrollView.contentOffset.x
    // 计算滑动的个数
    var pageIndex = Int(horizontalOffsetX) / Int(self.bounds.width)
    // 判断图像是否是倒数第二个
    if pageIndex == (self.handDataArray?.count)! - 1 {
        // 让图像滑动到UICollectionView的第二个Item的位置
        collectionView!.scrollToItem(at: IndexPath.init(row: 1, section: 0), at: .centeredHorizontally, animated: false)
        pageIndex = 1
    }
    if pageIndex == 0 {
        collectionView!.scrollToItem(at: IndexPath.init(row: ((self.handDataArray?.count)!-2), section: 0), at: .centeredHorizontally, animated: false)
        pageIndex = (self.handDataArray?.count)!-2
    }
    // 设置小白点的显示
    self.pageControl.currentPage = pageIndex - 1
}

10> 整体的使用

    // 轮播图的调用实现
    override func viewDidLoad() {
        super.viewDidLoad()
        // 编辑数据
        let imageArray = NSMutableArray.init(capacity: 0)
        for i in 0..<4 {
            let  str = String.init(format: "%d.jpg",i)
            imageArray.add(UIImage.init(named: str)!)
        }
        let suf = ShufflingView.init(frame: CGRect.init(x: 0, y: 64, width: self.view.frame.width, height: 160),dataArray: imageArray)
        suf.delegate = self
        self.view.addSubview(suf)
        
    }
    
    // MARK:  协议的实现
    func didSelecdItem(index: IndexPath) {
         print(index.row)
    }

上一篇下一篇

猜你喜欢

热点阅读