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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM