使用UICollectionView實現一個列表頭部拉伸效果(下拉放大)(OC 和 Swift)

先看效果圖
這裏寫圖片描述

突然發現沒有做出來之前都覺得蠻難的,做出來之後就覺得So Easy 大家都有這樣的感觸吧

做這個就重寫 UICollectionViewFlowLayout的幾個方法就可以

OC版本
創建一個類 CustomCollectionViewFlowLayout 繼承 UICollectionViewFlowLayout

//
//  CustomCollectionViewFlowLayout.m
// 
//
//  Created by GongHui_YJ on 16/8/4.
//  Copyright © 2016年 Yangjian. All rights reserved.
//

#import "CustomCollectionViewFlowLayout.h"

@implementation CustomCollectionViewFlowLayout

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

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {

    UICollectionView *collectionView = [self collectionView];
    UIEdgeInsets insets = [collectionView contentInset];
    CGPoint offset = [collectionView contentOffset];
    CGFloat minY = -insets.top;

    NSArray *attributes = [super layoutAttributesForElementsInRect:rect];

    if (offset.y < minY) {

        CGSize  headerSize = [self headerReferenceSize];
        CGFloat deltaY = fabsf(offset.y - minY);

        for (UICollectionViewLayoutAttributes *attrs in attributes) {

            if ([attrs representedElementKind] == UICollectionElementKindSectionHeader) {

                CGRect headerRect = [attrs frame];
                headerRect.size.height = MAX(minY, headerSize.height + deltaY);
                headerRect.origin.y = headerRect.origin.y - deltaY;
                [attrs setFrame:headerRect];
                break;
            }
        }
    }

    return attributes;
}

@end

在控制器中使用 先導入頭文件

// 創建collectionView
    CustomCollectionViewFlowLayout *flowLayout=[[CustomCollectionViewFlowLayout alloc] init];
    [flowLayout setSectionInset:UIEdgeInsetsMake(0, 0, 10, 0)];
    [flowLayout setItemSize:CGSizeMake(kScreenWidth / collectionCellW,  kScreenWidth / collectionCellW)];
    [flowLayout setHeaderReferenceSize:CGSizeMake(kScreenWidth, userInfoImageViewH)];
    [flowLayout setFooterReferenceSize:CGSizeMake(kScreenWidth, 83)];
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
    [flowLayout setMinimumInteritemSpacing:0.0];
    [flowLayout setMinimumLineSpacing:0.0];

    self.homeCollectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight - 44)collectionViewLayout:flowLayout];
    self.homeCollectionView.backgroundColor = kViewBackgroundColor;
    self.homeCollectionView.alwaysBounceVertical = YES;
    self.homeCollectionView.showsVerticalScrollIndicator = NO;
    //設置代理
    self.homeCollectionView.delegate = self;
    self.homeCollectionView.dataSource = self;
    [self.view addSubview:self.homeCollectionView];

    // 註冊表頭
    [self.homeCollectionView registerClass:[YJHeaderCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kCollectionHeaderView];

    // 註冊表尾
    [self.homeCollectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:kCollectionFooterView];

Swift版 喜歡swift 不需要導入頭文件那麼麻煩

//
//  CustomCollectionViewFlowLayout.swift
// 
//
//  Created by GongHui_YJ on 16/8/4.
//  Copyright © 2016年YangJian. All rights reserved.
//

import UIKit

class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout {

    override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
        return true
    }

    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let collectionView = self.collectionView
        let insets = collectionView?.contentInset
        let offset = collectionView?.contentOffset
        let minY = -((insets?.top)!)

        let attributesArray = super.layoutAttributesForElementsInRect(rect)
        if offset!.y < minY {
            let headerSize = self.headerReferenceSize
            let deltaY = CGFloat(fabsf(Float((offset?.y)! - CGFloat(minY))))

            for attrs:UICollectionViewLayoutAttributes in attributesArray! {

                if attrs.representedElementKind == UICollectionElementKindSectionHeader {
                    var headerRect = attrs.frame
                    headerRect.size.height = max(minY, headerSize.height + deltaY)
                    headerRect.origin.y = headerRect.origin.y - deltaY
                    attrs.frame = headerRect
                    break
                }
            }
        }

        return attributesArray
    }

}

在控制器 viewDidLoad方法實現

let customFlowLayout = CustomCollectionViewFlowLayout()
        customFlowLayout.headerReferenceSize = CGSizeMake(kScreenWidth, 203)
        customFlowLayout.footerReferenceSize = CGSizeMake(kScreenWidth, 83)
        customFlowLayout.minimumInteritemSpacing = 0
        customFlowLayout.minimumLineSpacing = 0
        customFlowLayout.itemSize = CGSizeMake(kScreenWidth / 3.000006, kScreenWidth / 3.00006)
        customFlowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 10, 0)

        self.homeCollectionView.setCollectionViewLayout(customFlowLayout, animated: true)
        self.homeCollectionView.backgroundColor = kViewBackgroundColor
        self.homeCollectionView.alwaysBounceVertical = true
        let nib = UINib(nibName: "CommonCollectionViewCell", bundle: nil)
        self.homeCollectionView.registerNib(nib, forCellWithReuseIdentifier: cellId)

        // 註冊表頭表尾
        let headerNib = UINib(nibName: "HeaderCollectionReusableView", bundle: nil)
        self.homeCollectionView.registerNib(headerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: collectionHeaderId)


        self.homeCollectionView.registerClass(UICollectionReusableView.classForCoder(), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: collectionFooterId)

注:不要實現UICollectionViewDelegateFlowLayout的代理方法了

發佈了58 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章