swift:無限圖片輪播器

swift:無限圖片輪播器

圖片輪播器用處很廣兜挨,什么廣告投放呀替久,新聞頭條滾動之類的箱锐,都是使用它。出于學(xué)習(xí)的目的用swift基于UICollectionView開發(fā)了一個無限循環(huán)的圖片輪播器埋同。附上Github源碼以及素材地址CyclePictureView州叠。下面是演示


適合人群

用swift寫了一個無限圖片輪播器,適合初學(xué)者莺禁。為了方便大家一步步自己開發(fā)留量,已經(jīng)把開發(fā)過程中的每一個階段都用了一個工程窄赋,當(dāng)然你也可以使用git回滾哟冬。而且在功能基本完成后楼熄,花了很大的心思對代碼進(jìn)行重構(gòu),讓代碼更加符合swift的編程模式浩峡。

編碼

1.完成本地圖片的顯示

  • 創(chuàng)建CyclePictureView.swift這是我們圖片輪播器主要的view可岂,在這一階段,我僅僅只是利用UIColleciotnView的流水布局效果達(dá)成了一個簡單的效果翰灾。
  • 創(chuàng)建CyclePictureCell.swift缕粹。這個是用于UIColleciotnView的cell,它代表顯示的每一張圖片
  • 創(chuàng)建LocalPictureController.swift,用于測試

這一階段十分簡單纸淮,大家參照源碼1.完成本地圖片的顯示工程應(yīng)該不會有問題

2.完成網(wǎng)絡(luò)圖片的顯示

  • 添加了網(wǎng)絡(luò)圖片加載的功能平斩,這里我沒有自己重寫圖片加載過程直接調(diào)用第三方框架Kingfisher,這個框架和oc的SDWebImage十分類似。其實事后我才發(fā)現(xiàn)Kingfisher跟SDWebImage的差距還是有很大咽块。如果想使用其他框架列如SDWebImage只需將CyclePictureCell中設(shè)置圖片的kf_setImageWithURL改成sd_setImageWithURL绘面。
  • 創(chuàng)建WebPictureController.swift,用于對網(wǎng)絡(luò)數(shù)據(jù)的測試侈沪,我提供了一個Image.plist文件揭璃,里面是一些網(wǎng)絡(luò)圖片的url和圖片對應(yīng)的描述。

這一階段如果是有經(jīng)驗的開發(fā)者就對我實現(xiàn)這兩種圖片加載的方式感到不爽了亭罪,因為這里是可以對代碼進(jìn)行重構(gòu)的瘦馍。當(dāng)然,對于初學(xué)者的我們应役,一定要以實現(xiàn)功能為主如果在項目一開始就考慮代碼這樣寫不好情组,那樣寫不好。那么你永遠(yuǎn)可能也邁不出項目第一步箩祥,會嚴(yán)重拖緩開發(fā)進(jìn)度呻惕。所以我們先實現(xiàn)功能,對于代碼的重構(gòu)滥比,一個階段一個階段的來亚脆,或者說你啥時候?qū)嵲谌滩涣肆耍蔷驼泶a吧盲泛。

3.完成文字顯示濒持,并暴露一些接口

  • 添加了圖片的描述文字,并暴露了一些接口寺滚。因為我們開發(fā)這個圖片輪播器是想以后自己能夠用到柑营,而往往對于不同規(guī)格的圖片輪播器,我們對于文字的大小什么的可能會不一樣村视。所以這些屬性必須提供給用戶官套,讓使用者能夠自己定制。

這里需要注意一點,父控件對于子控件的布局操作最好是放在layoutSubviews奶赔,因為只有在layoutSubviews這個方式里面才能保證子控件在你希望的地方顯示惋嚎。這個方法在控件最終顯示前會調(diào)用一次進(jìn)行最后的布局,當(dāng)然也不僅僅是這時候才調(diào)用站刑,附上layoutSubviews調(diào)用時機(jī).

1另伍、init初始化不會觸發(fā)layoutSubviews
2、addSubview會觸發(fā)layoutSubviews
3绞旅、設(shè)置view的Frame會觸發(fā)layoutSubviews摆尝,當(dāng)然前提是frame的值設(shè)置前后發(fā)生了變化
4、滾動一個UIScrollView會觸發(fā)layoutSubviews
5因悲、旋轉(zhuǎn)Screen會觸發(fā)父UIView上的layoutSubviews事件
6堕汞、改變一個UIView大小的時候也會觸發(fā)父UIView上的layoutSubviews事件 

舉個例子,就拿本項目來說晃琳,CyclePictureCell的子控件有用于顯示圖片的imageVIew和用于顯示文字的UILabel臼朗,那么我對這兩個控件的大小以及位置的設(shè)置,最好放在CyclePictureCelllayoutSubviews方法蝎土。ps:layoutSubviews一定得調(diào)用super.layoutSubviews()

4.完成無限滾動

  • 完成了無限滾動视哑,其思路說來就是讓我們顯示的cell"變多"。

假如我們有5張圖片,UICollectionView將會準(zhǔn)備用5個cell進(jìn)行顯示(當(dāng)然因為循環(huán)利用的機(jī)制在誊涯,所以創(chuàng)建出的cell并不一定是五個)挡毅。那么當(dāng)我們顯示到第五張圖片的時候,如果要繼續(xù)顯示那么暴构,應(yīng)該顯示第一張圖片跪呈。這時候如果強(qiáng)制的用UICollciontVIew的方法強(qiáng)制拉回第一個cell,會有一個非常難看的向左滑動的動畫取逾,而不是繼續(xù)向右滾動的動畫耗绿。

為了實現(xiàn)無限滾動,我只能把cell的數(shù)量變多砾隅,在五張圖片下误阻,我讓cell有500個或者更多,但是cell顯示的圖片卻還是只有我們設(shè)置的那五張晴埂。并且在第一次顯示的時候究反,讓顯示是cell是最中間的一張。這樣儒洛,就照成了無限循環(huán)的假象精耐。而且由于循環(huán)利用的機(jī)制的存在,是不用擔(dān)心效率問題的琅锻。

這里定時器的問題也需要額外注意一下卦停。反正要又這種意識向胡,只要用到了定時器就要擔(dān)心循環(huán)引用的問題。我的習(xí)慣是在開發(fā)的過程中惊完,把所有用到的控制器也好僵芹,自定義的view也好。我總會加上它的析構(gòu)方法deinit专执。

5.添加PageControl

  • 這里我添加了UIPageControlPageControl控件。同樣值得注意的是它的frame應(yīng)該在ayoutSubviews里面設(shè)置郁油。

到達(dá)這一步本股,其實大概功能也都差不多了。而且代碼量也有300多行了桐腌。是可以考慮對代碼進(jìn)行整理了(其實是我實在不能忍了)拄显。

6整理代碼,重構(gòu)圖片存取方式

  • UICollectionView的數(shù)據(jù)源和代理全部放進(jìn)了擴(kuò)展里面案站。這其實也是沒辦法的事情躬审,我總覺得讓一個View充當(dāng)數(shù)據(jù)源和代理是不符合思維邏輯的,但又找不到其他解決方式蟆盐,只要放進(jìn)擴(kuò)展承边。這樣讓CyclePictureView這個類的本體顯得沒那么臃腫

  • 創(chuàng)建AuxiliaryModels.swift文件。加載怎樣的數(shù)據(jù)石挂,以及怎樣的加載數(shù)據(jù)應(yīng)該不是我們的CyclePictureView關(guān)心的事情博助。所以CyclePictureView的職責(zé)只要把圖片的數(shù)據(jù)源(url、名字)存儲起來痹愚,并在cell需要的時候給他就好富岳,至于怎么樣顯示加載,那是cell的事情拯腮。所以我利用ImageBox來存儲圖片的數(shù)據(jù)源窖式。這里不得不感嘆swift中枚舉的強(qiáng)大。然后在下一步中动壤,將感受到swift2.0中協(xié)議的強(qiáng)大萝喘。

7.添加pageControl對齊模式,并且將無限滾動功能變成協(xié)議

  • 首先我是先對pageControl的功能進(jìn)行了一次增強(qiáng)琼懊,讓它的位置能夠被用戶所選擇蜒灰。于是我立即定義了一個枚舉PageControlAliment來表示能夠支持的對齊方式。剩下的操作無疑是在layoutSubviews中根據(jù)不同的枚舉計算不同的位置肩碟。

  • PageControlAlimentProtocol:本來完成對齊模式應(yīng)該分開一個工程再寫的强窖,請原諒這里我靈感來的太突然,停不下來了削祈。我的思路是這樣的:我是給pageControl添加了一個功能,然而這個功能對于CyclePictureView來說可以有也可以沒有翅溺。而且這個功能也不僅僅能夠用于CyclePictureView這個類脑漫,似乎是所有的擁有有UIPageControl這個控件的類(視圖),都可以有這個設(shè)置UIPageControl位置的功能咙崎。于是我想到了使用協(xié)議优幸。我要為這個功能設(shè)計一個協(xié)議,叫做PageControlAlimentProtocol褪猛,一個對齊協(xié)議网杆。任何一個View,你只要想方便的調(diào)整自己擁有UIPageControl伊滋,只要遵守這個協(xié)議碳却,協(xié)議便能夠幫你調(diào)節(jié)控件位置。于是協(xié)議我定義成這樣笑旺。

protocol PageControlAlimentProtocol: class{
    var pageControlAliment: PageControlAliment {get set}
    func AdjustPageControlPlace(pageControl: UIPageControl)
}

一個屬性昼浦,便是開始定義的位置類型的枚舉,要使用本協(xié)議筒主,必須得提供這個屬性关噪。還有協(xié)議一個方法,是調(diào)節(jié)位置的協(xié)議方法乌妙。這里我在協(xié)議的擴(kuò)展中給了它一個默認(rèn)的實現(xiàn)使兔。用戶在任何需要改變位置的代碼出直接調(diào)用即可。

  • EndlessCycleProtocol:這個協(xié)議的思路和上面那個協(xié)議幾乎一樣藤韵。不過這個協(xié)議抽取出來感覺有點牽強(qiáng)火诸。不過代碼確實是簡潔了。這里希望大牛們能夠指點

8.進(jìn)一步改進(jìn)代碼荠察,并添加對storyboard的支持

  • 首先是增加了CyclePictureView的代理協(xié)議CyclePictureViewDelegate置蜀,其實就是一個簡單的點擊事件的傳遞。
  • 改進(jìn)了一些代碼的邏輯悉盆。
  • 增加了對storyboard的支持盯荤,這里折騰了挺久,在從storyboard中加載的時候焕盟,不知道為什么會有莫名的偏移秋秤,找了好久才找到原因。

總結(jié)

在編碼過程中脚翘,我盡量多的使用swift的特性灼卢,代碼寫到第五步感覺和以前oc的思維都差不多。于是我強(qiáng)迫自己對代碼進(jìn)行修改来农。結(jié)果雖然是寫出來了不一樣的代碼鞋真,但是不知道有沒有過度重構(gòu),希望大家能夠指出不足之處沃于。當(dāng)然這個CyclePictureView圖片輪播器是可以拿到任何項目中去使用的涩咖。如果您發(fā)現(xiàn)任何BUG,或者有更好的建議或者意見海诲,歡迎您的指出。郵箱:wxl19950606@163.com.感謝您的支持檩互。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末特幔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子闸昨,更是在濱河造成了極大的恐慌蚯斯,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饵较,死亡現(xiàn)場離奇詭異拍嵌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)告抄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門撰茎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嵌牺,“玉大人打洼,你說我怎么就攤上這事∧娲猓” “怎么了募疮?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長僻弹。 經(jīng)常有香客問我阿浓,道長,這世上最難降的妖魔是什么蹋绽? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任芭毙,我火速辦了婚禮,結(jié)果婚禮上卸耘,老公的妹妹穿的比我還像新娘退敦。我一直安慰自己,他們只是感情好蚣抗,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布侈百。 她就那樣靜靜地躺著,像睡著了一般翰铡。 火紅的嫁衣襯著肌膚如雪钝域。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天锭魔,我揣著相機(jī)與錄音例证,去河邊找鬼。 笑死迷捧,一個胖子當(dāng)著我的面吹牛战虏,可吹牛的內(nèi)容都是我干的拣宰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼烦感,長吁一口氣:“原來是場噩夢啊……” “哼巡社!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起手趣,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤晌该,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绿渣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體朝群,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年中符,在試婚紗的時候發(fā)現(xiàn)自己被綠了姜胖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡淀散,死狀恐怖右莱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情档插,我是刑警寧澤慢蜓,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站郭膛,受9級特大地震影響晨抡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜则剃,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一耘柱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧棍现,春花似錦调煎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至朴肺,卻和暖如春窖剑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背戈稿。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工西土, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鞍盗。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓需了,卻偏偏與公主長得像跳昼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子肋乍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

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