我正在使用带有自定义布局的UICollectionView,该布局以网格格式布局单元格。可以有超过50行和50列。滚动在垂直和水平方向都会发生。目前,我正在prepareLayout
中进行所有布局设置并将其存储在数组中:
- (void)prepareLayout {
NSMutableArray *newLayoutInfo = [[NSMutableArray alloc] init];
NSMutableArray *newLinearLayoutInfor = [[NSMutableArray alloc] init];
NSInteger sectionCount = [self.collectionView numberOfSections];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
self.heightForRows = [delegate collectionViewHeightForAllRows];
self.totalWidthsForRows = [[NSMutableArray alloc] init];
for (int i = 0; i < sectionCount; i++) {
[self.totalWidthsForRows addObject:[NSNumber numberWithInt:0]];
}
for (NSInteger section = 0; section < sectionCount; section++) {
NSMutableArray *cellLayoutInfo = [[NSMutableArray alloc] init];
NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
for (NSInteger item = 0; item < itemCount; item++) {
indexPath = [NSIndexPath indexPathForItem:item inSection:section];
UICollectionViewLayoutAttributes *itemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
itemAttributes.frame = [self frameForCellAtIndexPath:indexPath];
[cellLayoutInfo addObject:itemAttributes];
[newLinearLayoutInfor addObject:itemAttributes];
}
[newLayoutInfo addObject:cellLayoutInfo];
}
self.layoutInfo = newLayoutInfo;
self.linearLayoutInfo = newLinearLayoutInfor;
}
然后在layoutAttributesForElementsInRect
我有:
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *rows = [self.linearLayoutInfo filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UICollectionViewLayoutAttributes *evaluatedObject, NSDictionary *bindings) {
return CGRectIntersectsRect(rect, [evaluatedObject frame]);
}]];
这没关系,但是当我有超过50列和50行时,它是滞后和跳跃的。我现在的问题是我必须设置
-(BOOL)shouldInvalidateLayoutForBoundsChange {
return YES;
}
这使得每次边界变化时都会准备好整个布局,不用说,这会对性能产生巨大影响,而且几乎无法滚动。单元格只包含不透明背景的文本,所以没有问题。
我确信我做得不对,必须有更好的方法。感谢您的帮助。
答案 0 :(得分:9)
在自定义流程布局中,我这样做,似乎有所帮助:
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return !(CGSizeEqualToSize(newBounds.size, self.collectionView.frame.size));
}
答案 1 :(得分:5)
-(BOOL)shouldInvalidateLayoutForBoundsChange {
return YES;
}
每次滚动时布局都会prepareLayout()
,这意味着准备中任何繁重的计算都会导致延迟练习,因此解决这个问题的一个可能方向是检查实际需要花费多少时间。一种可能性是内在的
for (NSInteger section = 0; section < sectionCount; section++)
{
// generate attributes ...
}
为了生成布局的属性。每次滚动时,每次这种概括重新运行时,它对滚动的影响似乎是跳跃和笨拙的。所以为了解决这个问题,或者至少要弄清楚这不是真正的麻烦,我建议在这个布局算法中设置一个标志,比如说, isScrolling ,代表布局需要的情况准备。每次在prepareLayout()
检查标记时,如果是是,那么我们就知道不需要 for loop 来重新生成所有属性,自第一次初始化布局以来,alreay exsit。
答案 2 :(得分:0)