Introducing Collection Views

什么是UICollectionView

UICollectionView是一種新的數(shù)據(jù)展示方式,簡單來說可以把他理解成多列的UITableView(請一定注意這是

UICollectionView的最最簡單的形式)。如果你用過iBooks的話,可能你還對書架布局有一定印象:一個(gè)虛擬書架上放著你下載和購買的各

類圖書,整齊排列迂卢。其實(shí)這就是一個(gè)UICollectionView的表現(xiàn)形式,或者iPad的iOS6中的原生時(shí)鐘應(yīng)用中的各個(gè)時(shí)鐘,也是

UICollectionView的最簡單的一個(gè)布局倍踪,如圖:

最簡單的UICollectionView就是一個(gè)GridView,可以以多列的方式將數(shù)據(jù)進(jìn)行展示索昂。標(biāo)準(zhǔn)的UICollectionView包含三個(gè)部分惭适,它們都是UIView的子類:

Cells 用于展示內(nèi)容的主體,對于不同的cell可以指定不同尺寸和不同的內(nèi)容楼镐,這個(gè)稍后再說

Supplementary Views 追加視圖 如果你對UITableView比較熟悉的話癞志,可以理解為每個(gè)Section的Header或者Footer,用來標(biāo)記每個(gè)section的view

Decoration Views 裝飾視圖 這是每個(gè)section的背景框产,比如iBooks中的書架就是這個(gè)


不管一個(gè)UICollectionView的布局如何變化凄杯,這三個(gè)部件都是存在的。再次說明秉宿,復(fù)雜的UICollectionView絕不止上面的幾幅圖戒突,關(guān)于較復(fù)雜的布局和相應(yīng)的特性,我會在本文稍后和下一篇筆記中進(jìn)行一些深入描睦。

實(shí)現(xiàn)一個(gè)簡單的UICollectionView

先從最簡單的開始膊存,UITableView是iOS開發(fā)中的非常非常非常重要的一個(gè)類,相信如果你是開發(fā)者的話應(yīng)該是對這個(gè)類非常熟悉了忱叭。實(shí)現(xiàn)一個(gè)

UICollectionView和實(shí)現(xiàn)一個(gè)UITableView基本沒有什么大區(qū)別隔崎,它們都同樣是datasource和delegate設(shè)計(jì)模式

的:datasource為view提供數(shù)據(jù)源,告訴view要顯示些什么東西以及如何顯示它們韵丑,delegate提供一些樣式的小細(xì)節(jié)以及用戶交互的相

應(yīng)爵卒。因此在本節(jié)里會大量對比collection view和table view來進(jìn)行說明,如果您還不太熟悉table

view的話撵彻,也是個(gè)對照著復(fù)習(xí)的好機(jī)會钓株。

UICollectionViewDataSource

section的數(shù)量 -numberOfSectionsInCollection:

某個(gè)section里有多少個(gè)item -collectionView:numberOfItemsInSection:

對于某個(gè)位置應(yīng)該顯示什么樣的cell -collectionView:cellForItemAtIndexPath:

實(shí)現(xiàn)以上三個(gè)委托方法实牡,基本上就可以保證CollectionView工作正常了。當(dāng)然轴合,還有提供Supplementary View的方法

collectionView:viewForSupplementaryElementOfKind:atIndexPath:

對于Decoration Views创坞,提供方法并不在UICollectionViewDataSource中,而是直接在UICollectionViewLayout類中的(因?yàn)樗鼉H僅是視圖相關(guān)受葛,而與數(shù)據(jù)無關(guān))题涨,放到稍后再說。

關(guān)于重用

為了得到高效的View奔坟,對于cell的重用是必須的携栋,避免了不斷生成和銷毀對象的操作,這與在UITableView中的情況是一致的咳秉。但值得注意的時(shí)婉支,在UICollectionView中,不僅cell可以重用澜建,Supplementary View和Decoration View也是可以并且應(yīng)當(dāng)被重用的向挖。在iOS5中,Apple對UITableView的重用做了簡化炕舵,以往要寫類似這樣的代碼:

UITableViewCell*cell=[tableViewdequeueReusableCellWithIdentifier:@"MY_CELL_ID"];

if(!cell)//如果沒有可重用的cell何之,那么生成一個(gè) {

cell=[[UITableViewCellalloc]init];

}

//配置cell,blablabla

returncell;

如果我們在TableView向數(shù)據(jù)源請求數(shù)據(jù)之前使用-registerNib:forCellReuseIdentifier:方法為

@“MY_CELL_ID”注冊過nib的話咽筋,就可以省下每次判斷并初始化cell的代碼溶推,要是在重用隊(duì)列里沒有可用的cell的話,runtime將自

動幫我們生成并初始化一個(gè)可用的cell奸攻。

這個(gè)特性很受歡迎蒜危,因此在UICollectionView中Apple繼承使用了這個(gè)特性,并且把其進(jìn)行了一些擴(kuò)展睹耐。使用以下方法進(jìn)行注冊:

-registerClass:forCellWithReuseIdentifier:

-registerClass:forSupplementaryViewOfKind:withReuseIdentifier:

-registerNib:forCellWithReuseIdentifier:

-registerNib:forSupplementaryViewOfKind:withReuseIdentifier:

比UITableView有兩個(gè)主要變化:一是加入了對某個(gè)Class的注冊辐赞,這樣即使不用提供nib而是用代碼生成的view也可以被接受為cell

了;二是不僅只是cell硝训,Supplementary View也可以用注冊的方法綁定初始化了响委。在對collection

view的重用ID注冊后,就可以像UITableView那樣簡單的寫cell配置了:

-(UICollectionView*)collectionView:(UICollectionView*)cvcellForItemAtIndexPath:(NSIndexPath*)indexPath{

MyCell*cell=[cvdequeueReusableCellWithReuseIdentifier:@”MY_CELL_ID”];

//Configure the cell's content

cell.imageView.image=...

returncell;

}

需要吐槽的是窖梁,對collection

view赘风,取重用隊(duì)列的方法的名字和UITableView里面不一樣了,在Identifier前面多加了Reuse五個(gè)字母窄绒,語義上要比以前清晰贝次,命

名規(guī)則也比以前嚴(yán)謹(jǐn)了..不知道Apple會不會為了追求完美而把UITableView中的命名不那么好的方法deprecate掉。

UICollectionViewDelegate

數(shù)據(jù)無關(guān)的view的外形啊彰导,用戶交互啊什么的蛔翅,由UICollectionViewDelegate來負(fù)責(zé):

cell的高亮

cell的選中狀態(tài)

可以支持長按后的菜單

關(guān)于用戶交互,UICollectionView也做了改進(jìn)位谋。每個(gè)cell現(xiàn)在有獨(dú)立的高亮事件和選中事件的delegate山析,用戶點(diǎn)擊cell的時(shí)候,現(xiàn)在會按照以下流程向delegate進(jìn)行詢問:

-collectionView:shouldHighlightItemAtIndexPath: 是否應(yīng)該高亮掏父?

-collectionView:didHighlightItemAtIndexPath: 如果1回答為是笋轨,那么高亮

-collectionView:shouldSelectItemAtIndexPath: 無論1結(jié)果如何,都詢問是否可以被選中赊淑?

-collectionView:didUnhighlightItemAtIndexPath: 如果1回答為是爵政,那么現(xiàn)在取消高亮

-collectionView:didSelectItemAtIndexPath: 如果3回答為是,那么選中cell

狀態(tài)控制要比以前靈活一些陶缺,對應(yīng)的高亮和選中狀態(tài)分別由highlighted和selected兩個(gè)屬性表示钾挟。

關(guān)于Cell

相對于UITableViewCell來說,UICollectionViewCell沒有這么多花頭饱岸。首先UICollectionViewCell不

存在各式各樣的默認(rèn)的style掺出,這主要是由于展示對象的性質(zhì)決定的,因?yàn)閁ICollectionView所用來展示的對象相比UITableView

來說要來得靈活苫费,大部分情況下更偏向于圖像而非文字汤锨,因此需求將會千奇百怪。因此SDK提供給我們的默認(rèn)的UICollectionViewCell結(jié)構(gòu)

上相對比較簡單百框,由下至上:

首先是cell本身作為容器view

然后是一個(gè)大小自動適應(yīng)整個(gè)cell的backgroundView闲礼,用作cell平時(shí)的背景

再其上是selectedBackgroundView,是cell被選中時(shí)的背景

最后是一個(gè)contentView铐维,自定義內(nèi)容應(yīng)被加在這個(gè)view上

這次Apple給我們帶來的好康是被選中cell的自動變化柬泽,所有的cell中的子view,也包括contentView中的子view方椎,在當(dāng)cell

被選中時(shí)聂抢,會自動去查找view是否有被選中狀態(tài)下的改變。比如在contentView里加了一個(gè)normal和selected指定了不同圖片的

imageView棠众,那么選中這個(gè)cell的同時(shí)這張圖片也會從normal變成selected琳疏,而不需要額外的任何代碼。

UICollectionViewLayout

終于到UICollectionView的精髓了…這也是UICollectionView和UITableView最大的不同闸拿。

UICollectionViewLayout可以說是UICollectionView的大腦和中樞空盼,它負(fù)責(zé)了將各個(gè)cell、

Supplementary View和Decoration Views進(jìn)行組織新荤,為它們設(shè)定各自的屬性揽趾,包括但不限于:

位置

尺寸

透明度

層級關(guān)系

形狀

等等等等…

Layout決定了UICollectionView是如何顯示在界面上的。在展示之前苛骨,一般需要生成合適的

UICollectionViewLayout子類對象篱瞎,并將其賦予CollectionView的collectionViewLayout屬性苟呐。關(guān)于

詳細(xì)的自定義UICollectionViewLayout和一些細(xì)節(jié),我將寫在之后一篇筆記中俐筋。

Apple為我們提供了一個(gè)最簡單可能也是最常用的默認(rèn)layout對象牵素,UICollectionViewFlowLayout。Flow

Layout簡單說是一個(gè)直線對齊的layout澄者,最常見的Grid View形式即為一種Flow

Layout配置笆呆。上面的照片架界面就是一個(gè)典型的Flow Layout。

首先一個(gè)重要的屬性是itemSize粱挡,它定義了每一個(gè)item的大小赠幕。通過設(shè)定itemSize可以全局地改變所有cell的尺寸,如果想要對

某個(gè)cell制定尺寸询筏,可以使用-collectionView:layout:sizeForItemAtIndexPath:方法榕堰。

間隔 可以指定item之間的間隔和每一行之間的間隔,和size類似屈留,有全局屬性局冰,也可以對每一個(gè)item和每一個(gè)section做出設(shè)定:

@property (CGSize) minimumInteritemSpacing

@property (CGSize) minimumLineSpacing

-collectionView:layout:minimumInteritemSpacingForSectionAtIndex:

-collectionView:layout:minimumLineSpacingForSectionAtIndex:

滾動方向 由屬性scrollDirection確定scroll view的方向,將影響Flow Layout的基本方向和由header及footer確定的section之間的寬度

UICollectionViewScrollDirectionVertical

UICollectionViewScrollDirectionHorizontal

Header和Footer尺寸 同樣地分為全局和部分灌危。需要注意根據(jù)滾動方向不同康二,header和footer的高和寬中只有一個(gè)會起作用。垂直滾動時(shí)section間寬度為該尺寸的高勇蝙,而水平滾動時(shí)為寬度起作用沫勿,如圖。

@property (CGSize) headerReferenceSize

@property (CGSize) footerReferenceSize

-collectionView:layout:referenceSizeForHeaderInSection:

-collectionView:layout:referenceSizeForFooterInSection:

縮進(jìn)

@property UIEdgeInsets sectionInset;

-collectionView:layout:insetForSectionAtIndex:

總結(jié)

一個(gè)UICollectionView的實(shí)現(xiàn)包括兩個(gè)必要部分:UICollectionViewDataSource和

UICollectionViewLayout味混,和一個(gè)交互部分:UICollectionViewDelegate产雹。而Apple給出的

UICollectionViewFlowLayout已經(jīng)是一個(gè)很強(qiáng)力的layout方案了。

幾個(gè)自定義的Layout

但是光是UICollectionViewFlowLayout的話翁锡,顯然是不夠用的蔓挖,而且如果單單是這樣的話,就和現(xiàn)有的開源各類Grid

View沒有區(qū)別了…UICollectionView的強(qiáng)大之處馆衔,就在于各種layout的自定義實(shí)現(xiàn)瘟判,以及它們之間的切換。先看幾個(gè)相當(dāng)

exiciting的例子吧~

比如角溃,堆疊布局:

圓形布局:

和Cover Flow布局:

所有這些布局都采用了同樣的數(shù)據(jù)源和委托方法拷获,因此完全實(shí)現(xiàn)了model和view的解耦。但是如果僅這樣减细,那開源社區(qū)也已經(jīng)有很多相應(yīng)的解決方案了匆瓜。

Apple的強(qiáng)大和開源社區(qū)不能比擬的地方在于對SDK的全局掌控,CollectionView提供了非常簡單的API可以令開發(fā)者只需要一次簡單調(diào)

用,就可以使用CoreAnimation在不同的layout之間進(jìn)行動畫切換驮吱,這種切換必定將大幅增加用戶體驗(yàn)茧妒,代價(jià)只是幾十行代碼就能完成的布局實(shí)

現(xiàn),以及簡單的一句API調(diào)用糠馆,不得不說現(xiàn)在所有的開源代碼與之相比嘶伟,都是相形見拙了…不得不佩服和感謝UIKit團(tuán)隊(duì)的努力怎憋。

原文地址:https://onevcat.com/2012/06/introducing-collection-views/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末又碌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绊袋,更是在濱河造成了極大的恐慌毕匀,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件癌别,死亡現(xiàn)場離奇詭異皂岔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)展姐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門躁垛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人圾笨,你說我怎么就攤上這事教馆。” “怎么了擂达?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵土铺,是天一觀的道長。 經(jīng)常有香客問我板鬓,道長悲敷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任俭令,我火速辦了婚禮后德,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抄腔。我一直安慰自己瓢湃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布妓柜。 她就那樣靜靜地躺著箱季,像睡著了一般。 火紅的嫁衣襯著肌膚如雪棍掐。 梳的紋絲不亂的頭發(fā)上藏雏,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼掘殴。 笑死赚瘦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的奏寨。 我是一名探鬼主播起意,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼病瞳!你這毒婦竟也來了揽咕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤套菜,失蹤者是張志新(化名)和其女友劉穎亲善,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逗柴,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛹头,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了戏溺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渣蜗。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖旷祸,靈堂內(nèi)的尸體忽然破棺而出耕拷,到底是詐尸還是另有隱情,我是刑警寧澤肋僧,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布斑胜,位于F島的核電站,受9級特大地震影響嫌吠,放射性物質(zhì)發(fā)生泄漏止潘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一辫诅、第九天 我趴在偏房一處隱蔽的房頂上張望凭戴。 院中可真熱鬧,春花似錦炕矮、人聲如沸么夫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽档痪。三九已至,卻和暖如春邢滑,著一層夾襖步出監(jiān)牢的瞬間腐螟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乐纸,地道東北人衬廷。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像汽绢,于是被迫代替她去往敵國和親吗跋。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

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

  • //聯(lián)系人:石虎 QQ: 1224614774昵稱:嗡嘛呢叭咪哄 什么是UICollectionView UICo...
    石虎132閱讀 3,406評論 0 15
  • 什么是UICollectionView宁昭? UICollectionView是一種新的數(shù)據(jù)展示方式跌宛,簡單來說可以把他...
    凌峰Mical閱讀 43,272評論 11 201
  • 文 | 奧格 本文為【奧格物語】原創(chuàng)首發(fā) 轉(zhuǎn)載請聯(lián)系后臺授權(quán) 抄襲必究 三毛秩冈,在荒漠里流浪的追夢人。 第一次看三毛...
    e26220db94a0閱讀 1,497評論 0 1
  • 連日加班斥扛,心情煩躁。周五晚上11點(diǎn)(那時(shí)候還在機(jī)房)跟經(jīng)理說我周末要出去玩丹锹,經(jīng)理無奈答應(yīng)稀颁。原先準(zhǔn)備去蘇州看...
    青梔檸閱讀 284評論 0 2
  • 財(cái)富自由:1慷慨心量&不論你擁有什么工具提前到;2善待他人&平和的的態(tài)度對待他人楣黍,微笑的對今天我遇到的人或動物3新...
    韋的消息閱讀 200評論 0 4