自定義UICollectionView的布局

不規(guī)則

關(guān)鍵方法

  • 1

      - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect掌呜;
    

    該方法用來返回rect范圍內(nèi)的 cell supplementary 以及 decoration的布局屬性layoutAttributes(這里保存著她們的尺寸注簿,位置捉片,indexPath等等),如果你的布局都在一個屏幕內(nèi)或者沒有復(fù)雜的計算惰说,這里可以返回全部的屬性數(shù)組性誉,如果涉及到復(fù)雜計算豁鲤,應(yīng)該進行判斷,返回區(qū)域內(nèi)的屬性數(shù)組惫恼,有時候為了方便直接返回了全部的屬性數(shù)組档押,不影響布局但可能會影響性能(如果你的item一屏幕顯示不完,那么這個方法會調(diào)用多次,當所有的item都加載完畢后令宿,在滑動collectionView時不會調(diào)用該方法的)叼耙。

  • 2

      - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
    

    該方法不是必須實現(xiàn)的粒没,即便你實現(xiàn)了筛婉,我們對collectionView的任何操作,也不會導(dǎo)致系統(tǒng)主動調(diào)用該方法癞松。該方法通常用來定制某個IndexPath的item的屬性爽撒。當然我們也可以重寫這個方法,將布局時相關(guān)的屬性設(shè)置放在這里拦惋,在- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect 或者 - (void)prepareLayout 中 需要創(chuàng)建用來返回給系統(tǒng)的屬性數(shù)組 主動調(diào)用這個方法匆浙,并添加帶可變數(shù)組中去返回給系統(tǒng)。當然我們也可以在 - (void)prepareLayout中 通過[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForRow:i inSection:0]] 獲取 每個indexPath的attributes厕妖,在- (void)prepareLayout中設(shè)置所有item的屬性首尼。看需求以及個人喜歡言秸。

  • 3

      - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;        
    

    用來刷新layout的软能,當我們返回yes的時候。如果我們的需求不需要實時的刷新layout举畸,那么最好判斷newBounds 和 我們的collectionView的bounds是否相同查排,如果不同就返回yes;(例如蘋果官方的lineLayout抄沮,因為每次滑動都要放大item跋核,所以這了就直接返回yes)。

  • 4

      - (void)prepareLayout;      
    

    第一次加載layout叛买、刷新layout砂代、以及- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;這個方法返回yes時,會調(diào)用率挣。實現(xiàn)該方法后應(yīng)該調(diào)用[super prepareLayout]保證初始化正確刻伊。該方法用來準備一些布局所需要的信息。該方法和init方法相似椒功,但該方法可能會被調(diào)用多次捶箱,所以一些不固定的計算(比如該計算和collectionView的尺寸相關(guān)),最好放在這里动漾,以保證collectionView發(fā)生變化時丁屎,自定義CollectionView能做出正確的反應(yīng)。

舉例

需要展示大小不相等的幾張圖片

效果圖

說明:圖片0比其他幾張圖片大旱眯,從而影響到布局悦屏,所以我們自定義一種布局@interface SixImageLayout : UICollectionViewLayout

兩個關(guān)鍵方法
返回所有cell的布局

    - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
self.cellCount = 6;   共6個cell
NSMutableArray *attributes = [NSMutableArray array];
for (NSInteger i = 0; i < self.cellCount; i ++) {
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
    //調(diào)用下面的方法返回
    UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
    [attributes addObject:attrs];
}
return attributes;
}

計算每個位置的布局

  • (UICollectionViewLayoutAttributes )layoutAttributesForItemAtIndexPath:(NSIndexPath )indexPath {
    UICollectionViewLayoutAttributes attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    attributes.size = CGSizeMake(kCellSize, kCellSize);
    if (indexPath.row == 0) {
    attributes.size = CGSizeMake(kCellSize
    2+1, kCellSize
    2+1);
    attributes.center = CGPointMake((kCellSize
    2+1)/2, (kCellSize2+1)/2);
    }
    else if (indexPath.row == 1) {
    attributes.center = CGPointMake(kCellSize
    2+2+kCellSize/2, kCellSize/2);
    } else if(indexPath.row == 2) {
    attributes.center = CGPointMake(kCellSize2+2+kCellSize/2, kCellSize+kCellSize/2+1);
    }else if (indexPath.row == 3) {
    attributes.center = CGPointMake(kCellSize/2, kCellSize
    2+2+kCellSize/2);
    } else if(indexPath.row == 4) {
    attributes.center = CGPointMake(kCellSize+kCellSize/2+1, kCellSize2+2+kCellSize/2);
    } else {
    attributes.center = CGPointMake(kCellSize
    2+2+kCellSize/2, kCellSize*2+2+kCellSize/2);
    }
    return attributes;}

然后設(shè)置布局

    SixImageLayout *sixLayout = [[SixImageLayout alloc] init];
    self.collectionV = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 110, kScreenWidth, kScreenWidth) collectionViewLayout:sixLayout];

參考文章

完整demo請移步本人github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末节沦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子础爬,更是在濱河造成了極大的恐慌甫贯,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件看蚜,死亡現(xiàn)場離奇詭異叫搁,居然都是意外死亡,警方通過查閱死者的電腦和手機供炎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門渴逻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人音诫,你說我怎么就攤上這事惨奕。” “怎么了竭钝?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵梨撞,是天一觀的道長。 經(jīng)常有香客問我香罐,道長卧波,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任庇茫,我火速辦了婚禮港粱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘旦签。我一直安慰自己查坪,他們只是感情好,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布宁炫。 她就那樣靜靜地躺著偿曙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪淋淀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天覆醇,我揣著相機與錄音朵纷,去河邊找鬼。 笑死永脓,一個胖子當著我的面吹牛袍辞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播常摧,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼搅吁,長吁一口氣:“原來是場噩夢啊……” “哼威创!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谎懦,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤肚豺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后界拦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吸申,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年享甸,在試婚紗的時候發(fā)現(xiàn)自己被綠了截碴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛉威,死狀恐怖日丹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蚯嫌,我是刑警寧澤哲虾,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站齐帚,受9級特大地震影響妒牙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜对妄,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一湘今、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧剪菱,春花似錦摩瞎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至构灸,卻和暖如春上渴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背喜颁。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工稠氮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人半开。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓隔披,卻偏偏與公主長得像,于是被迫代替她去往敵國和親寂拆。 傳聞我的和親對象是個殘疾皇子奢米,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

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