一、 前言
在现在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)
}