UICollectionViewLayout——layout实现

2017-04-12  本文已影响432人  reloadRen

UICollectionViewLayout——layout实现圆形布局

UICollectionViewLayout子类

http://git.oschina.net/null_549_8696/criclelayout

基本方法

UICollectionView 和 UITableView 最重要的区别就是 UICollectionView 并不知道如何布局,它把布局机制委托给了 UICollectionViewLayout 子类,默认的布局方式是 UICollectionFlowViewLayout 类提供的流式布局。不过也可以创建自己的布局方式,通过继承 UICollectionViewLayout。

子类需要覆盖父类以下3个方法:

- (void)prepareLayout

初始化参数,只会调动一次,可以设置每个块的属性,可设置的属性包括:

//配置item的布局位置
@property (nonatomic) CGRect frame;
//配置item的中心
@property (nonatomic) CGPoint center;
//配置item的尺寸
@property (nonatomic) CGSize size;
//配置item的3D效果
@property (nonatomic) CATransform3D transform3D;
//配置item的bounds
@property (nonatomic) CGRect bounds NS_AVAILABLE_IOS(7_0);
//配置item的旋转
@property (nonatomic) CGAffineTransform transform NS_AVAILABLE_IOS(7_0);
//配置item的alpha
@property (nonatomic) CGFloat alpha;
//配置item的z坐标
@property (nonatomic) NSInteger zIndex; // default is 0
//配置item的隐藏
@property (nonatomic, getter=isHidden) BOOL hidden; 
//item的indexpath
@property (nonatomic, strong) NSIndexPath *indexPath;
//获取item的类型
@property (nonatomic, readonly) UICollectionElementCategory representedElementCategory;
@property (nonatomic, readonly, nullable) NSString *representedElementKind; 
//一些创建方法
+ (instancetype)layoutAttributesForCellWithIndexPath:(NSIndexPath *)indexPath;
+ (instancetype)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind withIndexPath:(NSIndexPath *)indexPath;
+ (instancetype)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind withIndexPath:(NSIndexPath *)indexPath;
    

- (CGSize)collectionViewContentSize

布局首先要提供的信息就是滚动区域大小,这样collection view才能正确的管理滚动。布局对象必须在此时计算它内容的总大小,包括supplementary views和decoration views。

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

实现必须返回一个包含UICollectionViewLayoutAttributes对象的数组.其中包括:中心(center),尺寸(size),透明度(alpha),层级(zIndex),动画效果(transform3D),隐藏(hidden)等。UICollectionViewLayoutAttributes对象决定了cell的摆设位置(frame)。

传入参数rect是一个包含要显示区域的块。这个块的大小一般为2倍的collectionview的长度,只有滑动即将超过rect的范围,rect才会改变数值,保证了显示范围内的所有元素都在rect内。这个参数只是框定了显示范围,自定义layout的时候并不需要用到这个参数,而是使用contentOffset等属性,设置位置信息。

圆形布局实例

CircleLayout.h

#import <UIKit/UIKit.h>

@interface CircleLayout : UICollectionViewLayout

@end

CircleLayout.m

#import "CircleLayout.h"

#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
#define ITEM_SIZE 50

@interface CircleLayout(){
    NSMutableArray<UICollectionViewLayoutAttributes *> * _attributeAttay;
    int _itemCount; //item 个数
}

@end

@implementation CircleLayout

- (void)prepareLayout
{
    [super prepareLayout];
    //获取item的个数
    _itemCount = (int)[self.collectionView numberOfItemsInSection:0];
    _attributeAttay = [[NSMutableArray alloc]init];
    //先设定大圆的半径 取长和宽最短的
    CGFloat radius = MIN(self.collectionView.frame.size.width, self.collectionView.frame.size.height)/2;
    //计算圆心位置
    CGPoint center = CGPointMake(self.collectionView.frame.size.width/2, self.collectionView.frame.size.height/2);
    //设置每个item的大小为50*50 则半径为25
    for (int i=0; i<_itemCount; i++) {
        UICollectionViewLayoutAttributes * attris = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
        //设置item大小
        attris.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);
        //计算每个item的圆心位置
        //算出的x y值还要减去item自身的半径大小
        float x = center.x + cosf(2 * M_PI/_itemCount * i) * (radius - 50);
        float y = center.y + sinf(2 * M_PI/_itemCount * i) * (radius - 50);
        
        attris.center = CGPointMake(x, y);
        [_attributeAttay addObject:attris];
    }
}
//设置内容区域的大小
-(CGSize)collectionViewContentSize{
    return self.collectionView.frame.size;
}
//返回设置数组
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
    return _attributeAttay;
}

@end

controller使用

    CircleLayout * layout = [[CircleLayout alloc]init];
    UICollectionView * collect  = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight) collectionViewLayout:layout];
    collect.delegate=self;
    collect.dataSource=self;
    
    [collect registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellid"];
    [self.view addSubview:collect];
上一篇下一篇

猜你喜欢

热点阅读