7

我正在使用具有自定义布局的 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;
} 

这使得它在每次边界变化时都准备好整个布局,不用说,这对性能有很大的影响,你几乎不能滚动。单元格仅包含具有不透明背景的文本,因此没有问题。

我确信我做的不对,一定有更好的方法。我在这里先向您的帮助表示感谢。

4

3 回答 3

9

在自定义流程布局中,我这样做了,它似乎有帮助:

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    return !(CGSizeEqualToSize(newBounds.size, self.collectionView.frame.size));
}
于 2014-04-12T00:11:23.140 回答
5
-(BOOL)shouldInvalidateLayoutForBoundsChange {
       return YES;
} 

导致布局在prepareLayout()每次滚动时都进行,这意味着准备中的任何繁重计算都会导致实践滞后,因此解决此问题的一个可能方向是检查真正花费大量时间的内容。一种可能性是里面有什么

for (NSInteger section = 0; section < sectionCount; section++)
{
   // generate attributes ...
}

为了生成布局的属性。每次滚动,每次这个泛化都重新运行,所以它对滚动的影响显得跳跃和笨拙。所以为了解决这个问题,或者至少理清这不是真正的麻烦,我建议在这个布局算法中设置一个标志,比如isScrolling,代表布局需要准备的情况。每次 prepareLayout()检查标志时,如果它是YES,那么我们就会知道没有必要执行for 循环 来重新生成所有属性,这些属性自第一次初始化布局以来就已经存在。

于 2013-03-24T04:05:08.833 回答
0

好的我现在明白了。以下是我的建议:创建 3 个集合视图……一个用于列标题(每个单元格是列标题),一个用于行前导(每个单元格 = 1 个行前导),一个用于单元格的集合视图。然后当用户更改任何集合视图的滚动位置时,根据需要更新其他 2 个集合视图的滚动位置。

在此处输入图像描述

于 2013-03-02T21:42:55.920 回答