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

iOS UICollectionView 总结

2016-05-09 20:01 459 查看


1.最简单的UICollectionView

UICollectionView是一个使用起来比较复杂的视图,即使是最简单的实现,也必须提供数据源dataSource,和布局方法UICollectionViewLayout,才可以实现一个可见可用的视图效果。

与TableView相同,dataSource需要提供的是

collectionView:numberOfItemsInSection: //返回每段显示的数据个数

collectionView:cellForItemAtIndexPath: // 返回数据的显示cell获取cell必须使用dequeueReusableCellWithReuseIdentifier:forIndexPath:方法,与TableView不同的是,这里不会返回nil,而是必须把cell的类别注册到collectionView供此方法调用,否则会出错。

布局我们使用已经提供的UICollectionViewLayout的子类UICollectionViewFlowLayout,在初始化UICollectionView的时候传入
UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new];
UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:self.view.bounds collectionViewLayout:layout];
collectionView.dataSource = self;
layout.itemSize = CGSizeMake(50, 50); //设定大小


2.UICollectionViewCell详解

UICollectionViewCell不像UITableViewCell一样提供了可用的几种样式,因此建议实现其子类来使用。 子类实现时候的几个注意点:

所有的自定义View需要加入contentView中。

实现prepareForReuse对重用cell进行必要的清理。

定义selectedBackgroundView来实现选中时候的区分背景

使用前先需要先注册:
[collectionView registerClass:[CustomCollectionViewCell class] forCellWithReuseIdentifier:@“MyIdentifier”];


对于段头或者段尾等附加显示的元素,同样需要注册:
[collectionView registerClass:[CustomCollectionViewCell class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader(Footer) withReuseIdentifier:@“HeaderIdentifier"];


并提供相应的dataSource方法:
collectionView:viewForSupplementaryElementOfKind:atIndexPath:


别忘了还需要设置layout:

对于UICollectionViewFlowLayout来说,可以使用
head(foot)erReferenceSize
或者代理方法:- collectionView:layout:referenceSizeForHead(Foot)erInSection:


cell和SupplementaryView的indexPath是分别计数的,互不干扰。SupplementaryView中的Header和Footer计数也是分开的,尽管他们需要在同一个数据方法里面实现。


3.UICollectionView的选择

UICollectionView选择的delegate方法跟UITableView的选择基本一致,这里就不详细说了,比较简单。 略有不同的是,UICollectionView没有默认highlighted的颜色样式,需要自己通过代理方法设置,cell里面是选中的颜色,而不是highlighted的颜色,区别应当注意。


4.UICollectionView的插入删除和移动

与TableView不同,UICollectionView没有默认的删除和插入,也没有代理方法,而是直接调用其类方法即可
- insertItemsAtIndexPaths:  //插入
moveItemAtIndexPath:toIndexPath:  //移动
deleteItemsAtIndexPaths:  //删除


同样可以进行批量操作。
- performBatchUpdates:completion:


5.cell的拷贝和粘贴或者自定义操作

长按cell的时候出现可以出现菜单,这个菜单是由UIMenuController实现的,它包含了剪切、拷贝、粘贴、删除等等操作,要实现这个菜单,必须实现三个方法
collectionView:shouldShowMenuForItemAtIndexPath: //是否弹出菜单,需要返回YES
-  collectionView:canPerformAction:forItemAtIndexPath:withSender: //是否可以弹出事件
假如我们只想使用拷贝和粘贴,可以这样写:
- (BOOL)collectionView:(UICollectionView *)collectionView
canPerformAction:(SEL)action
forItemAtIndexPath:(NSIndexPath *)indexPath
withSender:(id)sender {
if ([NSStringFromSelector(action) isEqualToString:@"copy:"]
|| [NSStringFromSelector(action) isEqualToString:@"paste:"])
return YES;
return NO;
}

- collectionView:performAction:forItemAtIndexPath:withSender: //对事件进行相应操作


6.自定义布局

当UICollectionViewFlowLayout以及其子类不能满足布局的需求时,可以创造UICollectionViewLayout的子类进行自动布局。

简单来讲,自定义布局就是需要提供所有元素的位置,随后,collectionView:cellForItemAtIndexPath等方法会根据layout来请求元素。
自定义自动布局必须需要重写的方法有:
-collectionViewContentSize
返回collectionView的大小
-layoutAttributesForElementsInRect:
返回区域内元素的属性数组
-layoutAttributesForItemAtIndexPath:
返回cell的布局属性
-layoutAttributesForSupplementaryViewOfKind:atIndexPath:
返回SupplementaryView的布局属性(可选)
-layoutAttributesForDecorationViewOfKind:atIndexPath:
返回DecorationView的布局属性(可选)
-shouldInvalidateLayoutForBoundsChange:
边界变化时是否自动布局,返回BOOL


建议写法:

首先实现方法
- (void)prepareLayout {
此方法中计算出全部元素布局所需要的属性并以indexPath为关键字存入字典
cell属性的生成方法:
UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
SupplementaryView属性的生成方法:
UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:@"customId" withIndexPath:indexPath];
根据indexPath确定attr的frame,或者使用center和size属性来确定frame。
把attr保存到字典中
}

- (CGSize)collectionViewContentSize {
通过self.collectionView获取相关信息并计算大小
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
建立一个可变数组attributes
遍历所有存储的attr
如果frame存在于rect中,则加入数组
if(CGRectIntersectsRect(rect, attr.frame)){
[attributes addObject:attr];
}
返回数组
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
只需要返回存储字典里的独立属性即可。
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: