目录
* UICollectionView的定义
* UICollectionView快速构建GridView网格视图
* UICollectionView拖拽重排处理(iOS8.x-/iOS9.x+)
* UICollectionView实现简单轮播
UICollectionView的定义
UICollectionView同UITableView一样,是iOS中最常用到数据展示视图。
官方定义:
An object that manages an ordered collection of data items and presents them using customizable layouts.
提供管理有序数据集合且可定制布局能力的对象

UICollectionView显示内容时:
- 通过
dataSource获取cell - 通过
UICollectionViewLayout获取layout attributes布局属性 - 通过对应的
layout attributes对cell进行调整,完成布局
- 通过
UICollectionView交互则是通过丰富的delegate方法实现
iOS10中增加了一个新的预处理protocol UICollectionViewDataSourcePrefetching 帮助预加载数据 缓解大量数据加载带来的快速滑动时的卡顿
UICollectionView视图
一个标准的UICollectionView视图包括以下三个部分
UICollectionViewCell视图展示单元SupplementaryView追加视图,类似我们熟悉的UITableView中的HeaderView、FooterVIewDecorationView装饰视图
1.UICollectionView依然采用Cell重用的方式减小内存开支,所以需要我们注册并标记,同样,注册分为Class及nib两类
// register cell
if (_cellClassName) {
[_collectionView registerClass:NSClassFromString(_cellClassName) forCellWithReuseIdentifier:ReuseIdentifier];
}
if (_xibName) {
// xib
[_collectionView registerNib:[UINib nibWithNibName:_xibName bundle:nil] forCellWithReuseIdentifier:ReuseIdentifier];
}
2.Father Apple同样将重用机制带给了SupplementaryView,注册方法同Cell类似
// UIKIT_EXTERN NSString *const UICollectionElementKindSectionHeader NS_AVAILABLE_IOS(6_0);
// UIKIT_EXTERN NSString *const UICollectionElementKindSectionFooter NS_AVAILABLE_IOS(6_0);
- (void)registerClass:(nullable Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;
对于它尺寸的配置,同样交由Layout处理,如果使用的是UICollectionViewFlowLayout,可以直接通过headerReferenceSize或footerReferenceSize赋值
3.DecorationView装饰视图,是我们在自定义Custom Layout时使用
UICollectionViewDataSource及UICollectionViewDelegate
这个部分使用频率极高想必大家都非常熟悉,所以笔者列出方法,不再赘述。
UICollectionViewDataSource(* 需要着重关注下iOS9后出现的两个新数据源方法,在下文中介绍拖拽重排时会用到他们 *)
@required
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
@optional
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;
// The view that is returned must be retrieved from a call to -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath NS_AVAILABLE_IOS(9_0);
UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0);
- (void)collectionView:(UICollectionView *)collectionView willDisplaySupplementaryView:(UICollectionReusableView *)view forElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0);
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingSupplementaryView:(UICollectionReusableView *)view forElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath;
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath;
- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath;
官方注释解释了交互后调用的顺序
// (when the touch begins)
// 1. -collectionView:shouldHighlightItemAtIndexPath:
// 2. -collectionView:didHighlightItemAtIndexPath:
//
// (when the touch lifts)
// 3. -collectionView:shouldSelectItemAtIndexPath: or -collectionView:shouldDeselectItemAtIndexPath:
// 4. -collectionView:didSelectItemAtIndexPath: or -collectionView:didDeselectItemAtIndexPath:
// 5. -collectionView:didUnhighlightItemAtIndexPath:
使用代理的方式处理数据及交互,好处是显而易见的,代码功能分工非常明确,但是也造成了一定程度上的代码书写的繁琐。所以本文会在快速构建部分,介绍如何使用Block实现链式传参书写
UICollectionViewLayout布局
不同于UITableView的简单布局样式,UICollectionView提供了更加强大的布局能力,将布局样式任务分离成单独一个类管理,就是我们初始化时必不可少UICollectionViewLayout
Custom Layout通过UICollectionViewLayoutAttributes,配置不同位置Cell的诸多属性
@property (nonatomic) CGRect frame;
@property (nonatomic) CGPoint center;
@property (nonatomic) CGSize size;
@property (nonatomic) CATransform3D transform3D;
@property (nonatomic) CGRect bounds NS_AVAILABLE_IOS(7_0);
@property (nonatomic) CGAffineTransform transform NS_AVAILABLE_IOS(7_0);
@property (nonatomic) CGFloat alpha;
@property (n

本文详细介绍了UICollectionView的定义、数据源与代理、布局,并提供了快速构建GridView、实现拖拽重排(iOS8.x/iOS9.x+)以及轮播功能的教程。通过实例代码展示了如何实现拖拽重排的各个步骤,包括边缘检测和数据源更新。最后,总结了UICollectionView在iOS开发中的重要性和应用价值。

629

被折叠的 条评论
为什么被折叠?



