一、 前言
在現(xiàn)在App中首頁信息展示非常重要,那問題就來了,如何在有限的空間來展示更多的產(chǎn)品信息呢?隨著時代的進(jìn)步,App的開發(fā)人員找到了一種能夠滿足首頁信息更多展示的控件--輪播圖。在輪播圖的實(shí)現(xiàn)中多種多樣,今天我們介紹一個實(shí)現(xiàn)的方法。使用 UICollectionView來實(shí)現(xiàn),同時減少內(nèi)存資源的消耗。
二、為什么選擇 UICollectionView 做組件?
UICollectionView 可以減少內(nèi)存資源的消耗,它是有兩個Item進(jìn)行展示的。
UICollectionView 在Item 滑動的過程中十分流暢。
UICollectionView 可以實(shí)現(xiàn)各種樣式的效果。
三、本Demo 使用到的知識點(diǎn)如下
UICollectionView 的使用等一系列知識
對象類型的判斷 (is)
圖像的異步加載
通知的添加和發(fā)出
給一個類添加一個代理事件
定時器的使用
UIPageControl 的使用等一些列知識
如何解決 UICollectionViewCell 的復(fù)用問題
可變數(shù)組的一些對元素的基本操作
四、本 Demo 的實(shí)現(xiàn)效果
Untitled.gif
五、關(guān)鍵代碼的展示
1> UICollectionView的創(chuàng)建
// TODO: 創(chuàng)建 UICollectionView對象
func createCollectionView(_rect:CGRect) -> Void {
// 創(chuàng)建對象
collectionView = UICollectionView.init(frame:CGRect.init(x: 0, y: 0, width: _rect.size.width, height: _rect.size.height), collectionViewLayout:self.createFlowLayout())
// 設(shè)置代理
collectionView.delegate = self
collectionView.dataSource = self
// 隱藏活動標(biāo)尺
collectionView.showsHorizontalScrollIndicator = false
// 設(shè)置 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)
// 進(jìn)行渲染
self.addSubview(collectionView)
}
2> 布局對象的創(chuàng)建
// TODO: 創(chuàng)建布局對象
func createFlowLayout() -> UICollectionViewFlowLayout {
// 創(chuàng)建對象
let flowLayout = UICollectionViewFlowLayout.init()
// 設(shè)置滑動方向
flowLayout.scrollDirection = .horizontal
return flowLayout
}
3> UICollectionView 的代理事件的實(shí)現(xiàn)
// MARK: CollectionView的代理事件
// UICollectionView 返回的 Section 的個數(shù),也可以不寫該代理。默認(rèn)為一
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
// UICollectionView返回的Item個數(shù)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return (self.handDataArray?.count)!
}
// 設(shè)置 Item 的大小
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return self.bounds.size
}
// 設(shè)置 Item 之間的間隔
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0.0
}
// 創(chuàng)建和設(shè)置 UICollectionViewCell
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// 創(chuàng)建對象
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
// 防止cell復(fù)用產(chǎn)生
for item in cell.contentView.subviews {
item.removeFromSuperview()
}
// 創(chuàng)建展示對象
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)
// 返回創(chuàng)建對象
return cell
}
// CollectionView 的 Item 點(diǎn)擊事件
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> 網(wǎng)絡(luò)異步加載
// 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{
//將圖片數(shù)據(jù)賦予UIImage
let img = UIImage(data:data!)
imageView.image = img
self.handDataArray?.replaceObject(at: index.row, with: img as Any)
}
}) as URLSessionTask
//使用resume方法啟動任務(wù)
dataTask.resume()
6>可變數(shù)組的元素簡單操作
// 處理傳入的數(shù)據(jù)
func handlingData(array:NSArray) -> Int {
// 初始化可變數(shù)組
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> 定時器的創(chuàng)建
// 定時器的創(chuàng)建
func createTimer() -> Void {
timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true, block: { (timer) in
// 獲取 UICollectionView 的水平偏移
let horizontalOffsetX = self.collectionView.contentOffset.x
// 計(jì)算滑動的個數(shù)
var pageIndex = Int(horizontalOffsetX) / Int(self.bounds.width)
// 判斷圖像是否是倒數(shù)第二個
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
}
// 設(shè)置小白點(diǎn)的顯示
self.pageControl.currentPage = pageIndex - 1
})
}
8> 小白點(diǎn)的添加
// 小白點(diǎn)的創(chuàng)建
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> 滑動的效果實(shí)現(xiàn)
// CollectionView的滑動事件
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
self.createTimer()
// 獲取 UICollectionView 的水平偏移
let horizontalOffsetX = scrollView.contentOffset.x
// 計(jì)算滑動的個數(shù)
var pageIndex = Int(horizontalOffsetX) / Int(self.bounds.width)
// 判斷圖像是否是倒數(shù)第二個
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
}
// 設(shè)置小白點(diǎn)的顯示
self.pageControl.currentPage = pageIndex - 1
}
10> 整體的使用
// 輪播圖的調(diào)用實(shí)現(xiàn)
override func viewDidLoad() {
super.viewDidLoad()
// 編輯數(shù)據(jù)
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: 協(xié)議的實(shí)現(xiàn)
func didSelecdItem(index: IndexPath) {
print(index.row)
}