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
相关文章推荐
- ajax ExecuteNonQuery
- Buildbot初探
- 1007. Maximum Subsequence Sum
- 60 Permutation Sequence
- iOS之UIView简单动画
- 黑马程序员——GUI
- iOS中 DataBase SQL数据库 UI_高级
- iOS中 DataBase SQL数据库 UI_高级
- 关于UITableViewCell的自适应高度使用后的心得记录
- Android属性动画之ValueAnimator
- ZOJ 3911 Prime Query
- git使用之六——github协同工作的Fork+Pull Request
- UICollectionView
- FineUI开源版之TreeGrid实现
- iOS 手写代码UICollectionView
- IOS 开发学习(3): IOS UI架构设计
- UICollectionView的下拉刷新问题
- UESTC 1712 Easy Problem With Numbers (线段树区间修改+非互素逆元)
- UIMenuController使用
- The resource identified by this request is only capable of generating responses with characteristics