62-Swift之轮播图(UICollectionView)
2017-08-14 本文已影响29人
NetWork小贱
一、 前言
在现在App中首页信息展示非常重要,那问题就来了,如何在有限的空间来展示更多的产品信息呢?随着时代的进步,App的开发人员找到了一种能够满足首页信息更多展示的控件--轮播图。在轮播图的实现中多种多样,今天我们介绍一个实现的方法。使用 UICollectionView来实现,同时减少内存资源的消耗。
二、为什么选择 UICollectionView 做组件?
-
UICollectionView 可以减少内存资源的消耗,它是有两个Item进行展示的。
-
UICollectionView 在Item 滑动的过程中十分流畅。
-
UICollectionView 可以实现各种样式的效果。
三、本Demo 使用到的知识点如下
-
UICollectionView 的使用等一系列知识
-
对象类型的判断 (is)
-
图像的异步加载
-
通知的添加和发出
-
给一个类添加一个代理事件
-
定时器的使用
-
UIPageControl 的使用等一些列知识
-
如何解决 UICollectionViewCell 的复用问题
-
可变数组的一些对元素的基本操作
四、本 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)
}