iOS開發UI篇--使用UICollectionView實現一個列表頭部拉伸效果的案例

邏輯教育-楚陽發表於2018-11-23

一、案例演示

本案例Demo演示的是列表頭部具有拉伸的效果,具有良好的使用者體驗。
當列表的offsetY小於0的時候,頂部的圖片會跟隨手勢的下拉將頭部的寬高進行相應地縮放。如下圖所示:

iOS開發UI篇--使用UICollectionView實現一個列表頭部拉伸效果的案例
1.gif

二、知識儲備

2.1、自定義UICollectionViewFlowLayout

自定義UICollectionViewFlowLayout就是UICollectionView功能強大的精髓所在,它負責了將各個Cell、Supplementary View和Decoration Views進行組織和管理,可以高度定製內容的展現。

2.2、layoutAttributesForElementsInRect:方法

這是UICollectionViewFlowLayout佈局類中最重要的方法了,同時可能也是最容易讓人迷惑的方法。collection view呼叫這個方法並傳遞一個自身座標系統中的矩形過去。這個矩形代表了這個檢視的可見矩形區域(也就是它的bounds),你需要準備好處理傳給你的任何矩形。

你的實現必須返回一個包含UICollectionViewLayoutAttributes物件的陣列,為每一個cell包含這樣的一個物件,supplementary view或decoration view在矩形區域內是可見的。UICollectionViewLayoutAttributes類包含了collection view內item的所有相關佈局屬性。預設情況下,這個類包含frame,center,size,transform3D,alpha,zIndex屬性(properties),和hidden特性(attributes)。如果你的佈局想要控制其他檢視的屬性(比如,背景顏色),你可以建一個UICollectionViewLayoutAttributes的子類,然後加上你自己的屬性。

佈局屬性物件通過indexPath屬性和他們對應的cell,supplementary view或者decoration view關聯在一起。collection view為所有items從佈局物件中請求到佈局屬性後,它將會例項化所有檢視,並將對應的屬性應用到每個檢視上去。

注意!這個方法涉及到所有型別的檢視,也就是cell,supplementary views和decoration views。一個幼稚的實現可能會選擇忽略傳入的矩形,並且為collection view中的所有檢視返回佈局屬性。在原型設計和開釋出局階段,這是一個有效的方法。但是,這將對效能產生非常壞的影響,特別是可見cell遠少於所有cell數量的時候,collection view和佈局物件將會為那些不可見的檢視做額外不必要的工作。

2.3、-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;

當collection view的bounds改變時,佈局需要告訴collection view是否需要重新計算佈局。

三、關鍵程式碼分析

自定義UICollectionViewFlowLayout的實現

#import "StretchyHeaderCollectionViewLayout.h"

@implementation StretchyHeaderCollectionViewLayout

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    return YES;
}

- (UICollectionViewScrollDirection)scrollDirection{
    return UICollectionViewScrollDirectionVertical;
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    UICollectionView *collectionView = [self collectionView];
    CGPoint offset = [collectionView contentOffset];

    NSArray *attributes = [super layoutAttributesForElementsInRect:rect];

    if (offset.y<0) {
        CGFloat deltaY = fabs(offset.y);
        for (UICollectionViewLayoutAttributes *attrs in attributes ) {
            NSString *kind = [attrs representedElementKind];
            if (kind == UICollectionElementKindSectionHeader) {
                CGSize headerSize = [self headerReferenceSize];
                CGRect headRect = [attrs frame];
                headRect.size.height = headerSize.height+deltaY;
                headRect.size.width = headerSize.width +deltaY;
                headRect.origin.y = headRect.origin.y - deltaY;
                headRect.origin.x = headRect.origin.x - deltaY/2;
                [attrs setFrame:headRect];
                break;
            }
        }

    }

    return attributes;
}
@end
複製程式碼

四、Demo下載地址

Demo下載地址:這是一個我的iOS交流群:624212887,群檔案自行下載,不管你是小白還是大牛熱烈歡迎進群 ,分享面試經驗,討論技術, 大家一起交流學習成長!希望幫助開發者少走彎路。——點選:加入

如果覺得對你還有些用,就關注小編+喜歡這一篇文章。你的支援是我繼續的動力。

下篇文章預告:使用UICollectionView實現一個傾斜列表效果

文章來源於網路,如有侵權,請聯絡小編刪除。


相關文章