一、 前言
在現(xiàn)在App中首頁信息展示非常重要观话,那問題就來了频蛔,如何在有限的空間來展示更多的產(chǎn)品信息呢?隨著時(shí)代的進(jìn)步帽驯,App的開發(fā)人員找到了一種能夠滿足首頁信息更多展示的控件--輪播圖尼变。在輪播圖的實(shí)現(xiàn)中多種多樣浆劲,今天我們介紹一個(gè)實(shí)現(xiàn)的方法。使用 UICollectionView來實(shí)現(xiàn)度气,同時(shí)減少內(nèi)存資源的消耗膨报。
二、為什么選擇 UICollectionView 做組件院领?
UICollectionView 可以減少內(nèi)存資源的消耗够吩,它是有兩個(gè)Item進(jìn)行展示的。
UICollectionView 在Item 滑動(dòng)的過程中十分流暢强法。
UICollectionView 可以實(shí)現(xiàn)各種樣式的效果饮怯。
三、本Demo 使用到的知識(shí)點(diǎn)如下
UICollectionView 的使用等一系列知識(shí)
對象類型的判斷 (is)
圖像的異步加載
通知的添加和發(fā)出
給一個(gè)類添加一個(gè)代理事件
定時(shí)器的使用
UIPageControl 的使用等一些列知識(shí)
如何解決 UICollectionViewCell 的復(fù)用問題
可變數(shù)組的一些對元素的基本操作
四课竣、本 Demo 的實(shí)現(xiàn)效果
五置媳、關(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
// 隱藏活動(dòng)標(biāo)尺
collectionView.showsHorizontalScrollIndicator = false
// 設(shè)置 UICollectionView 分頁滑動(dòng)
collectionView.isPagingEnabled = true
// 注冊 cell
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId)
// 初始讓 UICollectionView 顯示第二個(gè) 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è)置滑動(dòng)方向
flowLayout.scrollDirection = .horizontal
return flowLayout
}
3> UICollectionView 的代理事件的實(shí)現(xiàn)
// MARK: CollectionView的代理事件
// UICollectionView 返回的 Section 的個(gè)數(shù)迂曲,也可以不寫該代理寥袭。默認(rèn)為一
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
// UICollectionView返回的Item個(gè)數(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方法啟動(dòng)任務(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> 定時(shí)器的創(chuàng)建
// 定時(shí)器的創(chuàng)建
func createTimer() -> Void {
timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true, block: { (timer) in
// 獲取 UICollectionView 的水平偏移
let horizontalOffsetX = self.collectionView.contentOffset.x
// 計(jì)算滑動(dòng)的個(gè)數(shù)
var pageIndex = Int(horizontalOffsetX) / Int(self.bounds.width)
// 判斷圖像是否是倒數(shù)第二個(gè)
if pageIndex == (self.handDataArray?.count)! - 1 {
// 讓圖像滑動(dòng)到UICollectionView的第二個(gè)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> 滑動(dòng)的效果實(shí)現(xiàn)
// CollectionView的滑動(dòng)事件
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
self.createTimer()
// 獲取 UICollectionView 的水平偏移
let horizontalOffsetX = scrollView.contentOffset.x
// 計(jì)算滑動(dòng)的個(gè)數(shù)
var pageIndex = Int(horizontalOffsetX) / Int(self.bounds.width)
// 判斷圖像是否是倒數(shù)第二個(gè)
if pageIndex == (self.handDataArray?.count)! - 1 {
// 讓圖像滑動(dòng)到UICollectionView的第二個(gè)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)
}