使用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的代理方法了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

建古

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值