自定义UICollectionView布局-线性布局

线性布局

上一节讲解了自定义布局的基本实现思路,这一节主要用自定义布局实现线性布局,做一个简单的图片浏览器效果。

自定义布局类

1. 自定义布局类

/// 继承自UICollectionViewFlowLayout,是因为流水布局有左右滚动的功能
@interface CYLineLayout : UICollectionViewFlowLayout

@end

2. 重新父类的方法

2.1 准备布局
///  准备操作  一般在这里设置一些初始化参数
- (void)prepareLayout
{
    // 必须要调用父类(父类也有一些准备操作)
    [super prepareLayout];

    CGFloat width = self.collectionView.frame.size.height * 0.7;
    self.itemSize = CGSizeMake(width, width);
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    self.minimumLineSpacing = 20;

    // 设置内边距
    CGFloat inset = (self.collectionView.frame.size.width - width) * 0.5;
    self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
}
2.2 返回collectionView上面所有元素(比如cell)的布局属性
///
///  返回collectionView上面所有元素(比如cell)的布局属性:这个方法决定了cell怎么排布
///  每个cell都有自己对应的布局属性:UICollectionViewLayoutAttributes
///  要求返回的数组中装着UICollectionViewLayoutAttributes对象
///
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray *array = [super layoutAttributesForElementsInRect:rect];

    // 计算 CollectionView 的中点
    CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5;

    for (UICollectionViewLayoutAttributes *attrs in array)
    {
        // 计算 cell 中点的 x 值 与 centerX 的差值
        CGFloat delta = ABS(centerX - attrs.center.x);
        CGFloat scale = 1 - delta / self.collectionView.frame.size.width;
        attrs.transform = CGAffineTransformMakeScale(scale, scale);
    }
    return array;
}
2.3 当uicollectionView的bounds发生改变时,是否要刷新布局
///  当uicollectionView的bounds发生改变时,是否要刷新布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}
2.4 返回collectionView最终的偏移量(最终的停留位置)
///  targetContentOffset :通过修改后,collectionView最终的contentOffset(取决定情况)
///
///  proposedContentOffset :默认情况下,collectionView最终的contentOffset
///  @param velocity              速率
///
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    // NSLog(@"%@",NSStringFromCGPoint(proposedContentOffset));
    CGSize size = self.collectionView.frame.size;

    // 计算可见区域的面积
    CGRect rect = CGRectMake(proposedContentOffset.x, proposedContentOffset.y, size.width, size.height);
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    // 计算 CollectionView 中点值
    CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;
    // 标记 cell 的中点与 UICollectionView 中点最小的间距
    CGFloat minDetal = MAXFLOAT;
    for (UICollectionViewLayoutAttributes *attrs in array)
    {
        if (ABS(minDetal) > ABS(centerX - attrs.center.x))
        {
            minDetal = attrs.center.x - centerX;
        }
    }
    return CGPointMake(proposedContentOffset.x + minDetal, proposedContentOffset.y);
}

3. 控制器使用布局

3.1 导入头文件
#import "CYLineLayout.h"
3.2 实例化布局
CYLineLayout *layout = [[CYLineLayout alloc]init];  // 线性布局
UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:frame collectionViewLayout:layout];
3.3 UICollectionView的数据源方法
// ……
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值