iOS開發:Swift實現的輪播圖、無限迴圈檢視控制元件
Github:https://github.com/lxypeter/CYCircularScrollView
輪播圖控制元件實現很多,基本都思路有兩種:1、使用UIScrollView + 2-3 個UIImageView的復位使用;2、使用UICollectionView。雖然網上已經有不少優秀的實現,但適逢開始學習Swift,而且這種旋轉木馬式的迴圈展現也有抽離的封裝的價值,於是自己著手實現了基於UICollectionView的輪播圖控制元件CYPicBannerScrollView及支援自定義檢視的迴圈控制元件CYCircularScrollView。先上效果圖:
安裝
CocoaPods
pod 'CYCircularScrollView'
CocoaPods版本需要在1.1.0以上
手動引入
你也可以手動將CYCircularScrollView拷貝到專案中,但注意專案中需要同時引入Kingfisher,因為在輪播圖控制元件** CYPicBannerScrollView**中直接使用了Kingfisher框架進行網路圖片載入。
如何使用
輪播圖控制元件:CYPicBannerScrollView
1. 初始化
CYPicBannerScrollView支援三種型別的資料來源:UIImage
、圖片連結字串
以及資料模型(Model)
,與之對應的有3種初始化方法。
- UIImage型別
convenience init(frame:CGRect, images:[Any]?, didSelected:((Int,Any)->())?)
//e.g.
let imageArray = [UIImage(named: "banner_1")!,UIImage(named: "banner_2")!,UIImage(named: "banner_3")!]
let bannerView = CYPicBannerScrollView(frame: CGRect.zero,
images:imageArray ) { (index, data) in
//click event
}
- 圖片連結字串
convenience init(frame:CGRect, urlStrings:[Any]?, placeholder:UIImage?, didSelected:((Int,Any)->())?)
//e.g.
let urlArray = ["www","www","www"]
let bannerView = CYPicBannerScrollView(frame: CGRect.zero,
urlStrings: urlArray,
placeholder: UIImage(named: "pic_placeholder")) { (index, data) in
//click event
}
- 資料模型(Model)
convenience init(frame:CGRect, models:[Any]?, placeholder:UIImage?, modelImage:@escaping (Any)->(CYImageResult), didSelected:((Int,Any)->())?)
//e.g.
let announceArray = [Announcement(title:"First Announcement",time:"2017-01-01",image:"p1"),
Announcement(title:"Second Announcement",time:"2017-01-02",image:"p2"),
Announcement(title:"Third Announcement",time:"2017-01-03",image:"p3")]
let bannerView = CYPicBannerScrollView(frame: CGRect.zero,
models: announceArray,
placeholder: UIImage(named: "pic_placeholder"),
modelImage: { (model) -> (CYImageResult) in
let announcement = model as! Announcement
return CYImageResult(data: UIImage(named: announcement.image)!, type: .image)
}) { (index, data) in
//click event
}
對於物件模型型別的初始化,需要在modelImage
閉包中根據資料模型返回圖片資料來源,支援直接返回UIImage如:CYImageResult(data: UIImage(named: model.image)!, type: .image)
或連結字串如:CYImageResult(data: "http://image.com/image", type: .urlString)
2. 自定義樣式
CYPicBannerScrollView支援以下形式的客製化
bannerView.autoScrollInterval = 3.0 //自動翻頁間隔,預設為5秒
bannerView.pageControlPosition = .right //PageControl的位置,預設為center
bannerView.pageControlOffset = UIOffset(horizontal: -10, vertical: -5) //PageControl的基於位置的偏移量
//自定義PageControl的樣式
bannerView.pageControl.backgroundColor = UIColor(displayP3Red: 51/255.0, green: 51/255.0, blue: 51/255.0, alpha: 0.8)
bannerView.pageControl.layer.cornerRadius = 8
支援自定義檢視的迴圈控制元件:CYCircularScrollView
要實現自定義檢視迴圈展示只需要四步
- 1.繼承
CYCircularScrollView
class CYAnnounceScrollView : CYCircularScrollView
- 2.覆寫
var cellClass:UICollectionViewCell.Type
屬性
override var cellClass:UICollectionViewCell.Type {
return CYAnnounceCell.self //迴圈的檢視型別,需為UICollectionViewCell子類
}
- 3.覆寫
func configureCollectionCell(_ cell:UICollectionViewCell, data:Any) -> UICollectionViewCell
方法
override func configureCollectionCell(_ cell:UICollectionViewCell, data:Any) -> UICollectionViewCell {
let announceCell = cell as! CYAnnounceCell
if let announcement:Announcement = data as? Announcement{
announceCell.announcement = announcement
}
return announceCell
}
- 4.根據需求覆寫屬性
override var scrollDirection:CYScrollDirection {
return .vertical//滾動方向,預設為.horizontal
}
override var isScrollEnabled:Bool {
return false//是否可以手動滾動,預設為true
}
此時你就能使用你自定義的檢視控制元件了~
let annouceScrollView = CYAnnounceScrollView(frame: CGRect.zero, datas: self.announceArray) { (index, data) in
//click event
}
更詳盡的使用可以參照Github上的Demo。
實現思路
CYCircularScrollView是以UICollectionView
為基礎的,藉助UICollectionView
的可重用特性,讓滾動的效果更加流暢,實現也更為簡單。而為了能夠實現無限迴圈滾動,在資料來源上作了如下處理:
當實際的資料來源容量大於1時,
UICollectionView
接收的資料量加2,在前後增添各一緩衝檢視,用以優化到達資料來源邊界時的滾動效果。同時監聽UICollectionView
代理下的滾動事件public func scrollViewDidScroll(_ scrollView: UIScrollView)
。
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
if self.dataArray == nil {
return
}
var index:Float
switch self.scrollDirection {
case .horizontal:
index = Float(scrollView.contentOffset.x * 1.0 / scrollView.frame.size.width)
case .vertical:
index = Float(scrollView.contentOffset.y * 1.0 / scrollView.frame.size.height)
}
if index < 0.25 {
self.collectionView.scrollToItem(at: IndexPath(item: self.dataArray!.count, section: 0), at: [.top,.left], animated: false)
}else if index >= Float(self.dataArray!.count+1) {
self.collectionView.scrollToItem(at: IndexPath(item: 1, section: 0), at: [.top,.left], animated: false)
}
let page = self.transferIndex(Int(index))
scrollToPage(page)
}
當UICollectionView
滾動至首項(實際資料來源末項的緩衝檢視)及尾項(實際資料來源首項的緩衝檢視)並即將展示完時,UICollectionView
立即以無動畫效果跳轉至緩衝檢視對應的實際項所在,以儘可能少的掉幀達到無限迴圈的效果。而當前頁數的監聽與重新整理也在該步完成,避免了當存在UIPageControl
等分頁控制元件時當前頁數的延後重新整理。相比於重複複製資料來源而達到無限迴圈效果的實現,這種方法一方面節省了記憶體空間,同時也避免了因為某些意外到達邊界時的斷層甚至崩潰。
以上。
相關文章
- iOS-無限迴圈輪播圖iOS
- 【Swift】自定義控制元件無限輪播 + 無限圖片輪播Swift控制元件
- 【iOS】自定義控制元件無限輪播 + 無限圖片輪播iOS控制元件
- iOS無限迴圈輪播圖(只使用三個imageView)iOSView
- iOS開發之ImageView複用實現圖片無限輪播iOSView
- iOS無限輪播圖片iOS
- 手把手、腦把腦教你實現一個無限迴圈的輪播控制元件控制元件
- 原生js系列之無限迴圈輪播元件JS元件
- iOS開發系列--無限迴圈的圖片瀏覽器iOS瀏覽器
- iOS開發專案實戰——Swift實現圖片輪播與瀏覽iOSSwift
- IOS 無限迴圈小視訊播放iOS
- Android常用控制元件-BannerView(無限輪播圖控制元件)Android控制元件View
- Swift應用案例 1.無限輪播Swift
- 利用RecyclerView實現無限輪播廣告條View
- ViewPager兩種方式實現無限輪播Viewpager
- 在 Flutter 中實現一個無限輪播Flutter
- 左右無縫輪播圖的實現
- 無限for迴圈(死迴圈)
- ViewPager實現左右無限迴圈滑動Viewpager
- 打造萬能的BannerView(ViewPager)無限輪播圖Viewpager
- 短視訊軟體開發,實現簡單的輪播圖效果
- iOS 輪播圖iOS
- 直播app開發,首頁輪播圖效果實現APP
- ViewPager最簡單的無限輪播Viewpager
- ViewPage實現輪播圖View
- Banner實現輪播圖
- js實現輪播圖JS
- CollectionView 無限輪播設計思路View
- 有間隙卡片縮放/無縫CollectionViewBanner無限輪播圖View
- JQuery實現圖片輪播無縫滾動jQuery
- 手動實現輪播圖(二):迴圈滾動、定時切換與指示器
- ScrollView 之 實現檢視的迴圈顯示View
- Java無限迴圈問題Java
- javascript無限迴圈滾動JavaScript
- 原生js實現輪播圖JS
- 圖片輪播元件實現元件
- Android輪播圖控制元件的實現詳解(附GitHub開源連結)Android控制元件Github
- Swiper輪播檢視器