使用流式布局
你可以使用具體的布局對(duì)象( UICollectionViewFlowLayout
類)在集合視圖中排列items
。流式布局實(shí)現(xiàn)了基于行的斷裂布局氧急,這意味著布局對(duì)象將單元格放置在一條線性路徑上颗胡,并盡可能地沿著該行容納多個(gè)單元格。當(dāng)布局對(duì)象在當(dāng)前行上的空間不足時(shí)吩坝,會(huì)創(chuàng)建一個(gè)新的行毒姨,并且繼續(xù)進(jìn)行布局過程。圖3-1顯示垂直滾動(dòng)流式布局的外觀钉寝。在這種情況下弧呐,線條水平排列,每一條新線位于前一條線之下瘩蚪。每一個(gè)分區(qū)的單元格可以選擇性地用分區(qū)頭和分區(qū)尾視圖來(lái)圍繞泉懦。
你可以使用流式布局來(lái)實(shí)現(xiàn)網(wǎng)格,也可以使用它來(lái)做更多其他的工作疹瘦。線性布局的思想可以應(yīng)用于很多不同的設(shè)計(jì)崩哩。例如,你可以調(diào)整間距沿著一個(gè)滾動(dòng)維度來(lái)創(chuàng)建items
的一行言沐,而不是具有items
的網(wǎng)格邓嘹。items
可以是不同的大小,這產(chǎn)生比傳動(dòng)網(wǎng)格更不對(duì)稱的東西险胰,但仍然具有線性流動(dòng)性汹押。這里有多種可能。
在xcode中你可以使用編程代碼或界面構(gòu)建器來(lái)配置流式布局起便。配置的步驟如下:
- 創(chuàng)建一個(gè)流式布局對(duì)象并把它賦值給集合視圖
- 配置
cells
的寬高 - 設(shè)置線間距和
items
之間的間距 - 如果想要分區(qū)頭和分區(qū)尾棚贾,指定它們的大小
- 給布局設(shè)置滾動(dòng)方向
重要:至少必須指定
cells
的寬高。如果沒有榆综,items
的寬高默認(rèn)為0妙痹,將永不可見。
自定義流式布局屬性
流式布局公開了幾個(gè)屬性來(lái)配置內(nèi)容的外觀鼻疮。當(dāng)設(shè)置的時(shí)候怯伊,這些屬性將在布局中均等地應(yīng)用于所有items
。例如判沟,使用流式布局的itemSize
屬性來(lái)設(shè)置cell
的大小會(huì)造成所有的cells
有相同的大小耿芹。
如果你想要?jiǎng)討B(tài)改變items
的間距或大小崭篡,可以使用UICollectionViewDelegateFlowLayout
協(xié)議中的方法。在賦值給集合視圖的同一委托對(duì)象上實(shí)現(xiàn)這些方法吧秕。如果存在給定的方法琉闪,則流式布局對(duì)象會(huì)調(diào)用該方法,代替使用它具有的固定值砸彬。然后塘偎,你的視線必須為集合視圖中的所有items
返回適當(dāng)?shù)闹怠?/p>
在流式布局中指定items
的大小
如果集合視圖中所有的items
都是相同的大小,那就給流式布局對(duì)象的itemSize
屬性賦值合適的寬高值拿霉。(始終以點(diǎn)為單位指定items
的大小)。這是為大小不變的內(nèi)容配置布局對(duì)象的最快方式咱扣。
如果你想要給你的cells
指定不同的大小绽淘,你必須實(shí)現(xiàn)集合視圖代理的collectionView:layout:sizeForItemAtIndexPath:
方法。你可以使用提供的索引路徑信息來(lái)給相應(yīng)的item
返回大小闹伪。在布局期間沪铭,流式布局對(duì)象在同一行上垂直居中,如圖3-2所示偏瓤。然后杀怠,該線的整體高度和寬度由該維度中的最大item
確定。
注意:當(dāng)你為
cells
指定不同大小厅克,單行上的items
數(shù)可能會(huì)有所不同赔退。
指定items
和行之間的間距
使用流式布局,你可以指定同一行上的items
之間的最小間距和連續(xù)行之間的最小間距证舟。請(qǐng)記住硕旗, 提供的間隔只是最小間隔。因?yàn)槿绾尾季謨?nèi)容女责,流式布局對(duì)象可能將item
之間的間距增大到大于指定的值漆枚。當(dāng)被布局的items
是不同大小時(shí),布局對(duì)象可以類似地增加實(shí)際的行間距抵知。
在布局期間墙基,流式布局對(duì)象將items
添加到當(dāng)前行,直到?jīng)]有足夠的空間來(lái)適應(yīng)整個(gè)item
刷喜。如果線足夠大残制,以適應(yīng)沒有額外空間的整數(shù)個(gè)items
,那么這些items
之間的間距將等于最小間距吱肌。如果在線的末尾有額外的空間痘拆,則布局對(duì)象會(huì)增加間隔間距,直到這些items
均勻地貼合在線條邊界內(nèi)氮墨,如圖3-3所示纺蛆。增加間距可以提供items
的整體外觀吐葵,并防止每條線末端有大間隙。
對(duì)于行間距桥氏,流式布局對(duì)象使用與item
之間的間距相同的技術(shù)温峭。如果所有的items
是相同的大小,則流式布局可以絕對(duì)地遵守最小行間距值字支,并且一行中的所有item
與下一行中的items
均勻地間隔開凤藏。如果items
的大小不同,則各items
之間的實(shí)際間距可能會(huì)有所不同堕伪。
圖3-4顯示當(dāng)items
的大小不同時(shí)最小行間距會(huì)發(fā)生什么變化揖庄。對(duì)于不同大小的items
, 流式布局對(duì)象從每個(gè)行中選擇在滾動(dòng)方向上尺寸最大的item
。例如欠雌,在垂直滾動(dòng)的布局中蹄梢,它在每一行中尋找最大高度的item
。然后富俄,將這些item
之間的間距設(shè)置為最小值禁炒。如果items
位于行的不同部分,如圖所示霍比,實(shí)際行間距似乎大于最小值幕袱。
與其他流式布局屬性一樣,可以使用固定間距值或動(dòng)態(tài)變化值悠瞬。行和item
間隔是逐個(gè)處理的们豌。因此,給定分區(qū)的所有items
的行和間隔間距相同阁危,但可能在各分區(qū)之間變化玛痊。可以使用流式布局對(duì)象的minimumLineSpacing
和minimumInteritemSpacing
靜態(tài)地設(shè)置間距屬性或者使用集合視圖代理的collectionView:layout:minimumLineSpacingForSectionAtIndex:
和collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
設(shè)置間距屬性狂打。
使用分區(qū)插圖來(lái)調(diào)整內(nèi)容的邊距
分區(qū)插圖是可用于調(diào)整布局cells
的空間的一種方式擂煞。你可以使用插圖在分區(qū)的頭部視圖之后和分區(qū)的尾部視圖之前插入間距。還可以使用插圖在內(nèi)容的兩邊插入間距趴乡。圖3-5顯示插圖如何影響垂直滾動(dòng)的流式布局中的一些內(nèi)容对省。
因?yàn)椴鍒D減少了可用于布局cells
的空間量,可以使用它們來(lái)限制給定行中cell
的數(shù)量晾捏。在非滾動(dòng)方向上指定插圖是限制每條線的空間的一種方法蒿涎。如果將該信息與cell
大小相結(jié)合,則可以控制每行上的cell
數(shù)惦辛。
知道何時(shí)將流式布局子類化
雖然可以不需要子類化而很有效地使用流式布局劳秋,但仍有時(shí)候你可能需要子類來(lái)獲取你需要的行為。表3-1列出了一些需要UICollectionViewFlowLayout
子類實(shí)現(xiàn)所需效果的場(chǎng)景。
表3-1 用于子類化UICollectionViewFlowLayout的方案
情節(jié) | 子類化的技巧 |
---|---|
你想要給你的布局添加一個(gè)新的補(bǔ)充視圖或者裝飾視圖 | 標(biāo)準(zhǔn)流式布局類支持只有分區(qū)頭和分區(qū)尾并沒有裝飾的視圖玻淑。為了支持附加的補(bǔ)充視圖和裝飾視圖嗽冒,你需要至少重寫下列方法:layoutAttributesForElementsInRect: (必須) layoutAttributesForItemAtIndexPath: (必須) layoutAttributesForSupplementaryViewOfKind:atIndexPath: (來(lái)支持新的補(bǔ)充視圖) layoutAttributesForDecorationViewOfKind:atIndexPath: (來(lái)支持新的裝飾視圖) 在你的layoutAttributesForElementsInRect: 方法中,可以給cell調(diào)用super方法來(lái)獲取布局屬性补履,然后在指定的矩形內(nèi)給一些新的補(bǔ)充視圖或者裝飾視圖添加這些屬性添坊。使用其他方法根據(jù)需求提供屬性。關(guān)于在布局期間為視圖提供屬性的更多信息箫锤,請(qǐng)看Creating Layout Attributes和Providing Layout Attributes for Items in a Given Rectangle. |
你想要調(diào)整流式布局返回的布局屬性 | 重寫layoutAttributesForElementsInRect: 方法和返回布局屬性的任何方法贬蛙。你的方法實(shí)現(xiàn)應(yīng)該調(diào)用super,修改父類提供的屬性谚攒,然后返回它們阳准。 關(guān)于深入討論這些方法所涉及的內(nèi)容。請(qǐng)看Creating Layout Attributes和Providing Layout Attributes for Items in a Given Rectangle. |
你想要給你的cells和視圖添加新的布局屬性 | 創(chuàng)建一個(gè)UICollectionViewLayoutAttributes 的自定義子類馏臭,并添加代表自定義布局信息所需的任何屬性溺职。子類化UICollectionViewFlowLayout 并重寫layoutAttributesClass 方法,在該方法的實(shí)現(xiàn)中位喂,返回你的自定義子類。你應(yīng)該也重寫layoutAttributesForElementsInRect: 方法乱灵,layoutAttributesForItemAtIndexPath: 方法塑崖,和一些可以返回布局屬性其他的方法。在你的自定義實(shí)現(xiàn)中痛倚,應(yīng)該給你定義的任何自定義屬性設(shè)置值规婆。 |
你想要指定要插入或刪除的item的初始位置或最終位置 | 默認(rèn)情況下,會(huì)為要插入或刪除的item創(chuàng)建一個(gè)簡(jiǎn)單的淡入淡出動(dòng)畫蝉稳。為了創(chuàng)建自定義動(dòng)畫抒蚜,你必須重寫下面的一些或所有方法:initialLayoutAttributesForAppearingItemAtIndexPath: initialLayoutAttributesForAppearingSupplementaryElementOfKind:atIndexPath: initialLayoutAttributesForAppearingDecorationElementOfKind:atIndexPath: finalLayoutAttributesForDisappearingItemAtIndexPath: finalLayoutAttributesForDisappearingSupplementaryElementOfKind:atIndexPath: finalLayoutAttributesForDisappearingDecorationElementOfKind:atIndexPath: 在這些方法的實(shí)現(xiàn)中,指定要在插入之前或刪除之后每個(gè)視圖具有的屬性耘戚。流式布局對(duì)象會(huì)使用你提供的這些屬性來(lái)執(zhí)行插入和刪除的動(dòng)畫嗡髓。如果你重寫這些方法,那么建議你重寫prepareForCollectionViewUpdates: 和finalizeCollectionViewUpdates 方法收津。你可以使用這些方法來(lái)跟蹤在當(dāng)前周期內(nèi)插入或刪除了哪些item饿这。關(guān)于如何插入和刪除工作的更多信息,請(qǐng)看Making Insertion and Deletion Animations More Interesting
|
還有一些情況下撞秋,正確的做法是從頭創(chuàng)建一個(gè)自定義布局长捧。在決定做這件事之前,花點(diǎn)時(shí)間考慮是否真的有必要吻贿。流式布局提供了許多適合于不同類型布局的可定制行為串结,并且因?yàn)樗峁┝耍砸子谑褂茫S多優(yōu)化以使其高效肌割。然而卧蜓,這并不是說(shuō)不應(yīng)該創(chuàng)建自定義布局,因?yàn)樵谀承┣闆r下這樣做絕對(duì)有意義声功。流式布局將滾動(dòng)方向限制為一個(gè)方向烦却,因此如果你的布局包含的內(nèi)容比屏幕在兩個(gè)方向上延伸得更遠(yuǎn),則自定義布局更有意義先巴。創(chuàng)建一個(gè)自定義布局是正確的決定其爵,如果你的布局不是一個(gè)網(wǎng)格或線分割的布局,如上所述伸蚯,如果item在布局中頻繁移動(dòng)摩渺,子類化流式布局會(huì)比創(chuàng)建自定義布局更復(fù)雜。
關(guān)于創(chuàng)建自定義布局更多信息剂邮,請(qǐng)看Creating Custom Layouts.
官方文檔地址
Using the Flow Layout