您的位置:首页 > 产品设计 > UI/UE

UICollectionView

2015-10-14 19:42 483 查看

UICollectionView基本属性



UIViewController需要继承UICollectionViewDataSource,UICollectionViewDelegateFlowLayout两个代理

//创建UICollectionView

- (void)createCollectionView
{
CGRect frame = CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height-20);

//创建集合视图,并指定布局对象
_collectionView = [[UICollectionView alloc] initWithFrame:frame collectionViewLayout:[self customLayout]];

_collectionView.backgroundColor = [UIColor redColor];

//设置代理
_collectionView.dataSource = self;
_collectionView.delegate = self;

//注册复用标识及item类型
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellId"];
//注册附加(头/尾)视图的复用标识及类型
[_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"headerId"];
[_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footerId"];

[self.view addSubview:_collectionView];
}


//创建布局对象

- (UICollectionViewLayout *)customLayout
{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];

//最小行间距
layout.minimumLineSpacing = 10;
//item的尺寸
layout.itemSize = CGSizeMake(100, 100);
//section内边距
layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
//附加视图尺寸,垂直滑动高度有效,水平滑动宽度有效
layout.headerReferenceSize = CGSizeMake(50, 50);
layout.footerReferenceSize = CGSizeMake(50, 50);

//设置滚动方向
//    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

return [layout autorelease];
}


//必须实现的代理方法

//返回item

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
//该方法也可以出列cell,使用前必须注册,否则会崩溃
//该方法会对本次出列的cell进行预配置(宽高等)以提高效率
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellId" forIndexPath:indexPath];

//给每个item设置图片
NSString *fullName = [[NSBundle mainBundle].bundlePath stringByAppendingPathComponent:_dataSource[indexPath.item]];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:fullName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[image autorelease]];
CGSize size = cell.frame.size;
imageView.frame = CGRectMake(0, 0, size.width, size.height);

[cell addSubview:imageView];
return cell;
}


//创建头/尾视图代理方法

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
UICollectionReusableView *supplementaryView = nil;
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
supplementaryView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"headerId" forIndexPath:indexPath];
supplementaryView.backgroundColor = [UIColor greenColor];
} else if ([kind isEqualToString:UICollectionElementKindSectionFooter]) {
supplementaryView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"footerId" forIndexPath:indexPath];
supplementaryView.backgroundColor = [UIColor blueColor];
}
//添加标题label
......
return supplementaryView;
}


简易自定义瀑布流

代码如下

//.h文件

#import <UIKit/UIKit.h>

@class WaterfallFlowLayout;

@protocol WaterfallFlowLayoutDelegate <NSObject>

- (CGFloat)heightForItemInLayout:(WaterfallFlowLayout *)layout AtIndexPath:(NSIndexPath *)indexPath;

@end

@interface WaterfallFlowLayout : UICollectionViewLayout

@property (nonatomic,assign)id<WaterfallFlowLayoutDelegate> delegate;

@property (nonatomic,assign)CGFloat itemSpacing;
@property (nonatomic,assign)NSInteger numberOfColumns;
@property (nonatomic,assign)UIEdgeInsets edgeInsets;

@end


//.m文件

#import "WaterfallFlowLayout.h"

@interface WaterfallFlowLayout ()
{
//用于记录每一列布局到的高度
NSMutableArray *_heightsOfColumns;
//用于记录每一个item的属性信息
NSMutableArray *_itemsAttributes;
}
@end

@implementation WaterfallFlowLayout

- (void)dealloc
{
[_heightsOfColumns release];
[_itemsAttributes release];
[super dealloc];
}

- (instancetype)init
{
if (self = [super init]) {
_heightsOfColumns = [[NSMutableArray alloc] init];
_itemsAttributes = [[NSMutableArray alloc] init];
}
return self;
}

- (void)setItemSpacing:(CGFloat)itemSpacing
{
if (_itemSpacing != itemSpacing) {
_itemSpacing = itemSpacing;
//会让布局失效,进行重新布局
[self invalidateLayout];
}
}

- (void)setNumberOfColumns:(NSInteger)numberOfColumns
{
if (_numberOfColumns != numberOfColumns) {
_numberOfColumns = numberOfColumns;
[self invalidateLayout];
}
}

- (void)setEdgeInsets:(UIEdgeInsets)edgeInsets
{
if (!UIEdgeInsetsEqualToEdgeInsets(self.edgeInsets, edgeInsets)) {
_edgeInsets = edgeInsets;
[self invalidateLayout];
}
}

/**
*  重写方法1:真正的布局在这里
*/
- (void)prepareLayout
{
[super prepareLayout];

//初始化布局的每一列的高度
if (_heightsOfColumns.count > 0) {
[_heightsOfColumns removeAllObjects];
}
for (NSInteger i=0; i<self.numberOfColumns; i++) {
[_heightsOfColumns addObject:@(self.edgeInsets.top)];
}
//清空属性数组
if (_itemsAttributes.count > 0) {
[_itemsAttributes removeAllObjects];
}

//计算每个item的宽度
CGFloat totalWidth = self.collectionView.frame.size.width;
CGFloat validWidth = totalWidth-self.edgeInsets.left-self.edgeInsets.right-(self.numberOfColumns-1)*self.itemSpacing;
CGFloat itemWidth = validWidth/self.numberOfColumns;
//布局每一个item
NSInteger totalItems = [self.collectionView numberOfItemsInSection:0];
for (NSInteger i=0; i<totalItems; i++) {
//构建IndexPath
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
//找到布局最短列的下标
NSInteger shortest = [self indexOfShortestColumn];
//向代理对象索取item高度
CGFloat itemHeight = [self.delegate heightForItemInLayout:self AtIndexPath:indexPath];
//计算坐标原点
CGFloat originX = self.edgeInsets.left+(itemWidth+self.itemSpacing)*shortest;
CGFloat originY = [_heightsOfColumns[shortest] floatValue];
//得出frame
CGRect frame = CGRectMake(originX, originY, itemWidth, itemHeight);
//创建属性对象并保存frame
UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
attr.frame = frame;
//保存属性信息
[_itemsAttributes addObject:attr];
//更新最短列的高度信息
[_heightsOfColumns replaceObjectAtIndex:shortest withObject:@(originY+itemHeight+self.itemSpacing)];
}
}

/**
*  重写方法2:返回所有与指定区域有交集的item的属性
*
*  @param rect 应该显示的区域
*
*  @return 所有符合要求的item的属性数组
*/
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *array = [NSMutableArray array];
for (UICollectionViewLayoutAttributes *attr in _itemsAttributes) {
//判断frame有无交集
if (CGRectIntersectsRect(attr.frame, rect)) {
[array addObject:attr];
}
}
return array;
}
/**
*  重写方法3:返回指定位置的item的属性(frame)
*
*  @param indexPath 位置
*
*  @return 指定位置的item属性信息
*/
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return _itemsAttributes[indexPath.item];
}

/**
*  重写方法4:返回集合视图包含内容的尺寸
*
*  @return 内存尺寸
*/
- (CGSize)collectionViewContentSize
{
CGFloat width = self.collectionView.frame.size.width;
NSInteger longest = [self indexOfLongestColumn];
CGFloat height = [_heightsOfColumns[longest] floatValue]-self.itemSpacing+self.edgeInsets.bottom;
return CGSizeMake(width, height);
}

//返回数组中最长的一列的下标
- (NSInteger)indexOfLongestColumn
{
NSInteger index = 0;
for (NSInteger i=1; i<_heightsOfColumns.count; i++) {
if ([_heightsOfColumns[i] floatValue] > [_heightsOfColumns[index] floatValue]) {
index = i;
}
}
return index;
}
//返回数组中最短的一列的下标
- (NSInteger)indexOfShortestColumn
{
NSInteger index = 0;
for (NSInteger i=1; i<_heightsOfColumns.count; i++) {
if ([_heightsOfColumns[i] floatValue] < [_heightsOfColumns[index] floatValue]) {
index = i;
}
}
return index;
}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: