swift:無限圖片輪播器

swift:無限圖片輪播器

圖片輪播器用處很廣,什么廣告投放呀,新聞頭條滾動之類的,都是使用它。出于學習的目的用swift基于UICollectionView開發了一個無限循環的圖片輪播器。附上Github源碼以及素材地址CyclePictureView。下面是演示


適合人群

用swift寫了一個無限圖片輪播器,適合初學者。為了方便大家一步步自己開發,已經把開發過程中的每一個階段都用了一個工程,當然你也可以使用git回滾。而且在功能基本完成后,花了很大的心思對代碼進行重構,讓代碼更加符合swift的編程模式。

編碼

1.完成本地圖片的顯示

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

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

2.完成網絡圖片的顯示

  • 添加了網絡圖片加載的功能,這里我沒有自己重寫圖片加載過程直接調用第三方框架Kingfisher,這個框架和oc的SDWebImage十分類似。其實事后我才發現Kingfisher跟SDWebImage的差距還是有很大。如果想使用其他框架列如SDWebImage只需將CyclePictureCell中設置圖片的kf_setImageWithURL改成sd_setImageWithURL
  • 創建WebPictureController.swift,用于對網絡數據的測試,我提供了一個Image.plist文件,里面是一些網絡圖片的url和圖片對應的描述。

這一階段如果是有經驗的開發者就對我實現這兩種圖片加載的方式感到不爽了,因為這里是可以對代碼進行重構的。當然,對于初學者的我們,一定要以實現功能為主如果在項目一開始就考慮代碼這樣寫不好,那樣寫不好。那么你永遠可能也邁不出項目第一步,會嚴重拖緩開發進度。所以我們先實現功能,對于代碼的重構,一個階段一個階段的來,或者說你啥時候實在忍不了了,那就整理代碼吧。

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

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

這里需要注意一點,父控件對于子控件的布局操作最好是放在layoutSubviews,因為只有在layoutSubviews這個方式里面才能保證子控件在你希望的地方顯示。這個方法在控件最終顯示前會調用一次進行最后的布局,當然也不僅僅是這時候才調用,附上layoutSubviews調用時機.

1、init初始化不會觸發layoutSubviews
2、addSubview會觸發layoutSubviews
3、設置view的Frame會觸發layoutSubviews,當然前提是frame的值設置前后發生了變化
4、滾動一個UIScrollView會觸發layoutSubviews
5、旋轉Screen會觸發父UIView上的layoutSubviews事件
6、改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件 

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

4.完成無限滾動

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

假如我們有5張圖片,UICollectionView將會準備用5個cell進行顯示(當然因為循環利用的機制在,所以創建出的cell并不一定是五個)。那么當我們顯示到第五張圖片的時候,如果要繼續顯示那么,應該顯示第一張圖片。這時候如果強制的用UICollciontVIew的方法強制拉回第一個cell,會有一個非常難看的向左滑動的動畫,而不是繼續向右滾動的動畫。

為了實現無限滾動,我只能把cell的數量變多,在五張圖片下,我讓cell有500個或者更多,但是cell顯示的圖片卻還是只有我們設置的那五張。并且在第一次顯示的時候,讓顯示是cell是最中間的一張。這樣,就照成了無限循環的假象。而且由于循環利用的機制的存在,是不用擔心效率問題的。

這里定時器的問題也需要額外注意一下。反正要又這種意識,只要用到了定時器就要擔心循環引用的問題。我的習慣是在開發的過程中,把所有用到的控制器也好,自定義的view也好。我總會加上它的析構方法deinit

5.添加PageControl

  • 這里我添加了UIPageControlPageControl控件。同樣值得注意的是它的frame應該在ayoutSubviews里面設置。

到達這一步,其實大概功能也都差不多了。而且代碼量也有300多行了。是可以考慮對代碼進行整理了(其實是我實在不能忍了)。

6整理代碼,重構圖片存取方式

  • UICollectionView的數據源和代理全部放進了擴展里面。這其實也是沒辦法的事情,我總覺得讓一個View充當數據源和代理是不符合思維邏輯的,但又找不到其他解決方式,只要放進擴展。這樣讓CyclePictureView這個類的本體顯得沒那么臃腫

  • 創建AuxiliaryModels.swift文件。加載怎樣的數據,以及怎樣的加載數據應該不是我們的CyclePictureView關心的事情。所以CyclePictureView的職責只要把圖片的數據源(url、名字)存儲起來,并在cell需要的時候給他就好,至于怎么樣顯示加載,那是cell的事情。所以我利用ImageBox來存儲圖片的數據源。這里不得不感嘆swift中枚舉的強大。然后在下一步中,將感受到swift2.0中協議的強大。

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

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

  • PageControlAlimentProtocol:本來完成對齊模式應該分開一個工程再寫的,請原諒這里我靈感來的太突然,停不下來了。我的思路是這樣的:我是給pageControl添加了一個功能,然而這個功能對于CyclePictureView來說可以有也可以沒有。而且這個功能也不僅僅能夠用于CyclePictureView這個類,似乎是所有的擁有有UIPageControl這個控件的類(視圖),都可以有這個設置UIPageControl位置的功能。于是我想到了使用協議。我要為這個功能設計一個協議,叫做PageControlAlimentProtocol,一個對齊協議。任何一個View,你只要想方便的調整自己擁有UIPageControl,只要遵守這個協議,協議便能夠幫你調節控件位置。于是協議我定義成這樣。

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

一個屬性,便是開始定義的位置類型的枚舉,要使用本協議,必須得提供這個屬性。還有協議一個方法,是調節位置的協議方法。這里我在協議的擴展中給了它一個默認的實現。用戶在任何需要改變位置的代碼出直接調用即可。

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

8.進一步改進代碼,并添加對storyboard的支持

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

總結

在編碼過程中,我盡量多的使用swift的特性,代碼寫到第五步感覺和以前oc的思維都差不多。于是我強迫自己對代碼進行修改。結果雖然是寫出來了不一樣的代碼,但是不知道有沒有過度重構,希望大家能夠指出不足之處。當然這個CyclePictureView圖片輪播器是可以拿到任何項目中去使用的。如果您發現任何BUG,或者有更好的建議或者意見,歡迎您的指出。郵箱:wxl19950606@163.com.感謝您的支持。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容