Swift-collectionView實現(xiàn)輪播圖(循環(huán)滾動)

輪播圖現(xiàn)在基本已經(jīng)是app的標準配件之一了幕随。一個實用的輪播圖控件無疑能在很大程度上提高我們的開發(fā)效率尘盼。擼主自己封裝了一個簡易的bannerView。


使用sd加載圖片抖僵,支持 horizontal 和 vertical 兩個滾動方向,可以設置 isAutoScroll 和自動滾動的duration 和媳。

這里將思路和關鍵代碼分享給大家砚婆。

循環(huán)滾動的思路如下圖:

1.如果只有一張圖淆珊,返回一個cell并展示這張圖

2.如果有多個圖,cell的個數(shù)=圖片個數(shù)+2.

3.展示的時候 第一個cell 展示最后一張圖 最后一個cell 展示第一張圖健芭,其他的cell按順序展示圖片县钥。

4.collectionView的起始偏移量設置為collectionView的width (滾動到第二個cell的位置)。

5.向右滑動collectionView慈迈,當滾動到(最后一個cell完全展示出來)最后一個cell時無動畫滾回第二個cell若贮,向左滑動,當滾動到第一個cell時痒留,無動畫滾動到倒數(shù)第二個cell谴麦。

6.如果設置的是自動滾動,則添加定時器伸头,每隔一段時間自動滾動到下一頁匾效。

?1.2.對應code:

func collectionView(_ collectionView:UICollectionView, numberOfItemsInSection section: Int) -> Int {

if(self.imgArr?.count)! >1{

return(self.imgArr?.count)! +2

? ? ? ? }

return1

? ? }

3.對應code:

func collectionView(_ collectionView:UICollectionView, cellForItemAt indexPath: IndexPath) ->UICollectionViewCell{

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID,for: indexPath) as! BannerCollectionCell

cell.placeholder =self.placeholder

ifindexPath.row ==0{

cell.imgUrl =self.imgArr?.last

}elseifindexPath.row == (self.imgArr?.count)! +1{

cell.imgUrl =self.imgArr?.first

}else{

cell.imgUrl =self.imgArr?[indexPath.row -1]

? ? ? ? }

returncell

? ? }

4.對應code:

override func willMove(toSuperview newSuperview:UIView?) {

guard newSuperview !=nilelse{

return

? ? ? ? }

super.willMove(toSuperview: newSuperview)

// 如果imgArr 為 nil return

ifself.imgArr ==nil{

return

? ? ? ? }

guard (self.imgArr?.count)! >1else{

self.collectionView.isScrollEnabled =false

return

? ? ? ? }

scrollTo(crtPage:0+1, animated:false)

ifself.isAutoScroll ==true{

? ? ? ? ? ? addTimer()

? ? ? ? }

? ? }

我這里將滾動到第二個cell的時機設置到了?willMove(toSuperview newSuperview: UIView?)??

5.對應code

func scrollViewDidScroll(_ scrollView:UIScrollView) {

var offset =CGFloat(0)

ifself.mode == .horizontal {

? ? ? ? ? ? offset = scrollView.contentOffset.x

}else{

? ? ? ? ? ? offset = scrollView.contentOffset.y

? ? ? ? }


let x =self.mode == .horizontal ?self.frame.size.width :self.frame.size.height


ifoffset ==0{

scrollTo(crtPage: (self.imgArr?.count)!, animated:false)

self.pageControl.currentPage = (self.imgArr?.count)! -1

}elseifoffset ==CGFloat((self.imgArr?.count)! +1) * x {

scrollTo(crtPage:1, animated:false)

self.pageControl.currentPage =0

}else{

self.pageControl.currentPage = lroundf(Float(offset/self.frame.size.width)) -1

? ? ? ? }

? ? }

6.對應code:

? ? fileprivate func addTimer() {

ifself.timer ==nil{

self.timer = Timer.scheduledTimer(timeInterval:self.duration, target:self, selector:#selector(nextPage), userInfo: nil, repeats: true)

RunLoop.current.add(self.timer!, forMode: RunLoopMode.commonModes)

? ? ? ? }

? ? }

? ? @objc fileprivate func nextPage() {

if(self.imgArr?.count)! >1{

var crtPage =0

ifself.mode == .horizontal {

crtPage = lroundf(Float(self.collectionView.contentOffset.x/self.frame.size.width))

}else{

crtPage = lroundf(Float(self.collectionView.contentOffset.y/self.frame.size.height))

? ? ? ? ? ? }

scrollTo(crtPage: crtPage +1, animated:true)

? ? ? ? }

? ? }

添加定時器后需要在scrollVIew的代理方法里實現(xiàn):

開始拖拽collectionView時停止計時器,停止拖拽后重新啟動定時器恤磷。

func scrollViewWillBeginDragging(_ scrollView:UIScrollView) {

// pause

self.timer?.fireDate = Date.distantFuture

? ? }


func scrollViewDidEndDragging(_ scrollView:UIScrollView, willDecelerate decelerate: Bool) {

// resume

self.timer?.fireDate = Date.init(timeIntervalSinceNow:self.duration)

? ? }

以上就實現(xiàn)循環(huán)滾動的思路面哼。

擼主這里使用的是collectionView,使用起來比較方便簡潔 扫步。還有一種方法是使用 scrollView里面添加3個子view魔策,通過子view的循環(huán)使用來達到類似的效果,其實現(xiàn)思路也類似以上河胎。

完整代碼請移步github:https://github.com/zh-ios/BannerView-Swift.git

如有問題歡迎指出 闯袒。

在code 測試過程發(fā)現(xiàn)一個有意思現(xiàn)象:

? ? ? ? // 注意:下面這兩個屬性有沖突(hidesForSinglePage優(yōu)先級比較高),當設置了pageControl.hidesForSinglePage = true 時游岳,如果不止有一頁那么再設置pageControl.isHidden = true 沒有卵用8橄拧!吭历!堕仔。反之,如果不設置這個屬性則可以通過 isHidden 這個屬性控制pageControll的顯示和隱藏晌区。

? ? ? ? self.pageControl.hidesForSinglePage = true

//? ? ? ? self.pageControl.isHidden = true

這就是所謂的“就近原則”吧摩骨。具體可以參照https://my.oschina.net/zhxx/blog/663226這篇控件對齊方式的博客通贞。


https://blog.csdn.net/weixin_34267123/article/details/91633067

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市恼五,隨后出現(xiàn)的幾起案子昌罩,更是在濱河造成了極大的恐慌,老刑警劉巖灾馒,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茎用,死亡現(xiàn)場離奇詭異,居然都是意外死亡睬罗,警方通過查閱死者的電腦和手機轨功,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來容达,“玉大人古涧,你說我怎么就攤上這事』ㄑ危” “怎么了羡滑?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長算芯。 經(jīng)常有香客問我柒昏,道長,這世上最難降的妖魔是什么熙揍? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任昙楚,我火速辦了婚禮,結(jié)果婚禮上诈嘿,老公的妹妹穿的比我還像新娘堪旧。我一直安慰自己,他們只是感情好奖亚,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布淳梦。 她就那樣靜靜地躺著,像睡著了一般昔字。 火紅的嫁衣襯著肌膚如雪爆袍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天作郭,我揣著相機與錄音陨囊,去河邊找鬼。 笑死夹攒,一個胖子當著我的面吹牛蜘醋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咏尝,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼压语,長吁一口氣:“原來是場噩夢啊……” “哼啸罢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起胎食,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤扰才,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后厕怜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衩匣,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年粥航,在試婚紗的時候發(fā)現(xiàn)自己被綠了琅捏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡躁锡,死狀恐怖午绳,靈堂內(nèi)的尸體忽然破棺而出置侍,到底是詐尸還是另有隱情映之,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布蜡坊,位于F島的核電站杠输,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏秕衙。R本人自食惡果不足惜蠢甲,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望据忘。 院中可真熱鬧鹦牛,春花似錦、人聲如沸勇吊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汉规。三九已至礼殊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間针史,已是汗流浹背晶伦。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留啄枕,地道東北人婚陪。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像频祝,于是被迫代替她去往敵國和親近忙。 傳聞我的和親對象是個殘疾皇子竭业,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容