iOS:UICollectionView纯自定义的布局:堆叠式布局、圆式布局 (一般用来制作相册)

集合视图的自动布局:UICollectionViewLayout是抽象根类,必须用它的子类才能创建实例,下面是重写的方法,计算item的布局属性

//每一次重新布局前,都会准备布局(苹果官方推荐使用该方法进行一些初始化)

-(void)prepareLayout

 

//重写layoutAttributesForItemAtIndexPath,返回每一个item的布局属性(流式布局内部已经帮助完成)

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

 

//是否要重新刷新布局(只要显示的item边界发生改变就重新布局)

//只要每一次重新布局内部就会调用下面的layoutAttributesForElementsInRect:获取所有cell(item)的属性

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

 

//返回需要重新布局的所有item的属性

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect

 

🐷下面的这两个布局可以直接带走使用,不需要做任何其他的操作,欧耶

 

堆叠式布局代码如下:

CustomStackLayout.h

#import <UIKit/UIKit.h>

@interface CustomStackLayout : UICollectionViewLayout

@end

CustomStackLayout.m

#import "CustomStackLayout.h"

#define RANDOM_0_1  arc4random_uniform(100)/100.0

/*
 由于CustomStackLayout是直接继承自UICollectionViewLayout的,父类没有帮它完成任何的布局,因此,
 需要用户自己完全重新对每一个item进行布局,也即设置它们的布局属性UICollectionViewLayoutAttributes
*/

@implementation CustomStackLayout

//重写shouldInvalidateLayoutForBoundsChange,每次重写布局内部都会自动调用
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{

    return YES;
}

//重写collectionViewContentSize,可以让collectionView滚动
-(CGSize)collectionViewContentSize
{
    return CGSizeMake(400, 400);
}

//重写layoutAttributesForItemAtIndexPath,返回每一个item的布局属性
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    //创建布局实例
    UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    
    //设置布局属性
    attrs.size = CGSizeMake(100, 100);
    attrs.center = CGPointMake(self.collectionView.frame.size.width*0.5, self.collectionView.frame.size.height*0.5);
    
    //设置旋转方向
    //int direction = (i % 2 ==0)? 1: -1;
    
    NSArray *directions = @[@0.0,@1.0,@(0.05),@(-1.0),@(-0.05)];
    
    //只显示5张
    if (indexPath.item >= 5)
    {
        attrs.hidden = YES;
    }
    else
    {
        //开始旋转
        attrs.transform = CGAffineTransformMakeRotation([directions[indexPath.item]floatValue]);
        
        //zIndex值越大,图片越在上面
        attrs.zIndex = [self.collectionView numberOfItemsInSection:indexPath.section] - indexPath.item;
    }

    return attrs;
}


//重写layoutAttributesForElementsInRect,设置所有cell的布局属性(包括item、header、footer)
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *arrayM = [NSMutableArray array];
    NSInteger count = [self.collectionView numberOfItemsInSection:0];
    
    //给每一个item创建并设置布局属性
    for (int i = 0; i < count; i++)
    {
        //创建item的布局属性
        UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
        
         [arrayM addObject:attrs];
    }
    return arrayM;
}

@end

 

圆式布局代码如下:

CustomCircleLayout.h

#import <UIKit/UIKit.h>

@interface CustomCircleLayout : UICollectionViewLayout

@end

CustomCirclelayout.m

#import "CustomCircleLayout.h"

@implementation CustomCircleLayout


//重写shouldInvalidateLayoutForBoundsChange,每次重写布局内部都会自动调用
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

//重写layoutAttributesForItemAtIndexPath,返回每一个item的布局属性
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    //创建布局实例
    UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    
    //设置item的大小
    attrs.size = CGSizeMake(50, 50);
    
    //设置圆的半径
    CGFloat circleRadius = 70;
    
    //设置圆的中心点
    CGPoint circleCenter = CGPointMake(self.collectionView.frame.size.width*0.5, self.collectionView.frame.size.height *0.5);
    
    //计算每一个item之间的角度
    CGFloat angleDelta = M_PI *2 /[self.collectionView numberOfItemsInSection:indexPath.section];
    
    //计算当前item的角度
    CGFloat angle = indexPath.item * angleDelta;
    
    //计算当前item的中心
    CGFloat x = circleCenter.x + cos(angle)*circleRadius;
    CGFloat y = circleCenter.y - sin(angle)*circleRadius;
    
    //定位当前item的位置
    attrs.center = CGPointMake(x, y);
    
    //设置item的顺序,越后面的显示在前面
    attrs.zIndex = indexPath.item;
    
    return attrs;
}


//重写layoutAttributesForElementsInRect,设置所有cell的布局属性(包括item、header、footer)
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *arrayM = [NSMutableArray array];
    NSInteger count = [self.collectionView numberOfItemsInSection:0];
    
    //给每一个item创建并设置布局属性
    for (int i = 0; i < count; i++)
    {
        //创建item的布局属性
        UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
        
        [arrayM addObject:attrs];
    }
    return arrayM;
}

@end

 

堆叠式布局演示:                                               圆式布局演示:

        

 

github: https://github.com/xiayuanquan/XYQCollectionLayout.git

posted @ 2015-11-22 12:00  XYQ全哥  阅读(4072)  评论(0编辑  收藏  举报