UICollectionViewLayout——layout实现圆形布局
UICollectionViewLayout子类
http://git.oschina.net/null_549_8696/criclelayout
基本方法
UICollectionView 和 UITableView 最重要的区别就是 UICollectionView 并不知道如何布局,它把布局机制委托给了 UICollectionViewLayout 子类,默认的布局方式是 UICollectionFlowViewLayout 类提供的流式布局。不过也可以创建自己的布局方式,通过继承 UICollectionViewLayout。
子类需要覆盖父类以下3个方法:
- prepareLayout
- layoutAttributesForElementsInRect:(CGRect)rect
- collectionViewContentSize
- (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];
网友评论