UICollectionView

来源:互联网 发布:照片美图软件 编辑:程序博客网 时间:2024/06/11 03:09

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
0 0
原创粉丝点击