iOS开发进阶之旅-自定义UICollectionViewFlowlayout
来源:互联网 发布:js 获取端口号 编辑:程序博客网 时间:2024/06/08 10:29
为了实现自定义UICollectionViewFlowLayout的常规做法是继承UICollectionViewFlowLayout类,然后重载下列方法:
-(CGSize)collectionViewContentSize
- 返回collectionView的内容的尺寸
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
- 返回rect中的所有的元素的布局属性
- 返回的是包含UICollectionViewLayoutAttributes的NSArray
UICollectionViewLayoutAttributes可以是cell,追加视图或装饰视图的信息,通过不同的UICollectionViewLayoutAttributes初始化方法可以得到不同类型的UICollectionViewLayoutAttributes:
- layoutAttributesForCellWithIndexPath:
- layoutAttributesForSupplementaryViewOfKind:withIndexPath:
- layoutAttributesForDecorationViewOfKind:withIndexPath:
-(UICollectionViewLayoutAttributes )layoutAttributesForItemAtIndexPath:(NSIndexPath )indexPath
- 返回对应于indexPath的位置的cell的布局属性
-(UICollectionViewLayoutAttributes )layoutAttributesForSupplementaryViewOfKind:(NSString )kind atIndexPath:(NSIndexPath *)indexPath
- 返回对应于indexPath的位置的追加视图的布局属性,如果没有追加视图可不重载
-(UICollectionViewLayoutAttributes * )layoutAttributesForDecorationViewOfKind:(NSString)decorationViewKind atIndexPath:(NSIndexPath )indexPath
- 返回对应于indexPath的位置的装饰视图的布局属性,如果没有装饰视图可不重载
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
- 当边界发生改变时,是否应该刷新布局。如果YES则在边界变化(一般是scroll到其他地方)时,将重新计算需要的布局信息。
另外需要了解的是,在初始化一个UICollectionViewLayout实例后,会有一系列准备方法被自动调用,以保证layout实例的正确。
首先,-(void)prepareLayout将被调用,默认下该方法什么没做,但是在自己的子类实现中,一般在该方法中设定一些必要的layout的结构和初始需要的参数等。
之后,-(CGSize) collectionViewContentSize将被调用,以确定collection应该占据的尺寸。注意这里的尺寸不是指可视部分的尺寸,而应该是所有内容所占的尺寸。collectionView的本质是一个scrollView,因此需要这个尺寸来配置滚动行为。
接下来-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect被调用,这个没什么值得多说的。初始的layout的外观将由该方法返回的UICollectionViewLayoutAttributes来决定。
另外,在需要更新layout时,需要给当前layout发送 -invalidateLayout,该消息会立即返回,并且预约在下一个loop的时候刷新当前layout,这一点和UIView的setNeedsLayout方法十分类似。在-invalidateLayout后的下一个collectionView的刷新loop中,又会从prepareLayout开始。
#import "EqualSpaceFlowLayout.h"
const staticint bottomInset = 10;
@interface EqualSpaceFlowLayout()
@property (nonatomic,strong) NSMutableArray *itemAttributes;
@end
@implementation EqualSpaceFlowLayout
- (id)init
{
if (self = [superinit]) {
self.scrollDirection =UICollectionViewScrollDirectionVertical;
self.minimumInteritemSpacing =4;
self.minimumLineSpacing =0;
self.sectionInset =UIEdgeInsetsMake(bottomInset,15, bottomInset, 15);//UIEdgeInsetsMake(10, 10, 10, 10);
}
returnself;
}
#pragma mark - Methods to Override
- (void)prepareLayout
{
[superprepareLayout];
NSInteger itemCount = [[selfcollectionView] numberOfItemsInSection:0];
self.itemAttributes = [NSMutableArrayarrayWithCapacity:itemCount];
CGFloat xOffset =self.sectionInset.left;
CGFloat yOffset =self.sectionInset.top;
CGFloat xNextOffset =self.sectionInset.left;
for (NSInteger idx =0; idx < itemCount; idx++) {
NSIndexPath *indexPath = [NSIndexPathindexPathForItem:idx inSection:0];
CGSize itemSize = [self.delegatecollectionView:self.collectionViewlayout:selfsizeForItemAtIndexPath:indexPath];
xNextOffset+=(self.minimumInteritemSpacing + itemSize.width);
if (xNextOffset > [selfcollectionView].bounds.size.width - self.sectionInset.right) {
xOffset = self.sectionInset.left;
xNextOffset = (self.sectionInset.left +self.minimumInteritemSpacing + itemSize.width);
yOffset += (itemSize.height +self.minimumLineSpacing);
}
else
{
xOffset = xNextOffset - (self.minimumInteritemSpacing + itemSize.width);
}
UICollectionViewLayoutAttributes *layoutAttributes =
[UICollectionViewLayoutAttributeslayoutAttributesForCellWithIndexPath:indexPath];
layoutAttributes.frame =CGRectMake(xOffset, yOffset, itemSize.width, itemSize.height);
[_itemAttributesaddObject:layoutAttributes];
}
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return (self.itemAttributes)[indexPath.item];
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
return [self.itemAttributesfilteredArrayUsingPredicate:[NSPredicatepredicateWithBlock:^BOOL(UICollectionViewLayoutAttributes *evaluatedObject,NSDictionary *bindings) {
returnCGRectIntersectsRect(rect, [evaluatedObjectframe]);
}]];
}
- (CGSize)collectionViewContentSize{
//获取最后一个cell的frame拿到最Y值加上bottomInset就是collection
if (self.itemAttributes &&self.itemAttributes.count >0) {
UICollectionViewLayoutAttributes *layoutAttributes = WKC_ObjectAtIndex(self.itemAttributes,self.itemAttributes.count -1);
CGRect lastFrame = layoutAttributes.frame;
returnCGSizeMake([selfcollectionView].bounds.size.width,CGRectGetMaxY(lastFrame)+bottomInset);
}else{
[selfprepareLayout];
UICollectionViewLayoutAttributes *layoutAttributes = WKC_ObjectAtIndex(self.itemAttributes,self.itemAttributes.count -1);
CGRect lastFrame = layoutAttributes.frame;
returnCGSizeMake([selfcollectionView].bounds.size.width,CGRectGetMaxY(lastFrame)+bottomInset);
}
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
returnNO;
}
@end
- iOS开发进阶之旅-自定义UICollectionViewFlowlayout
- ios-自定义UICollectionViewFlowLayout
- iOS开发 - UICollectionViewFlowLayout 流水布局
- 自定义UICollectionViewFlowLayout
- 自定义UICollectionViewFlowLayout
- 自定义UICollectionViewFlowLayout
- iOS学习之—— UICollectionViewFlowLayout
- iOS学习之—— UICollectionViewFlowLayout
- iOS开发进阶之单元测试
- iOS开发进阶之单元测试
- iOS开发进阶之图说
- iOS开发之如何进阶
- UI_UICollectionView_自定义UICollectionViewFlowLayout
- UICollectionViewFlowLayout自定义(圆圈)
- Android开发进阶之自定义view
- iOS-UICollectionViewFlowLayout 流水布局
- iOS开发进阶之旅-WebViewJavascriptBridge的使用
- 初章之IOS开发进阶学习
- Handler的学习之路--Handler的用法(1)
- C++中的static关键字(杂谈)
- tiku网学习记录
- recycler添加ripple效果
- 机器学习实战(5)--SVM(Support vector machine)(四)
- iOS开发进阶之旅-自定义UICollectionViewFlowlayout
- apache主配置文件概述
- 自己动手丰衣足食之日历
- tiku网学习记录
- 【GPS】如何理解轨道倾角大于90
- Spring 4.0使用日记(持续更新)
- poj3278-两种方法的比较
- PLSQL存储过程及存储函数
- android动画详解五 layout,插值与评估器