I use a UICollectionView with a custom layout that exposes the cells as a grid. There can be more than 50 rows and 50 columns. Scrolling occurs both vertically and horizontally. I am currently doing the layout setup in prepareLayout and storing it in arrays:
- (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; }
Then in layoutAttributesForElementsInRect I:
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect { NSArray *rows = [self.linearLayoutInfo filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UICollectionViewLayoutAttributes *evaluatedObject, NSDictionary *bindings) { return CGRectIntersectsRect(rect, [evaluatedObject frame]); }]];
This works fine, but it is backward and nervous when I have more than 50 columns and 50 rows. The problem that I have now is that I have to install
-(BOOL)shouldInvalidateLayoutForBoundsChange { return YES; }
This forces him to cook the entire layout every time the boundaries change, which, of course, has a huge impact on performance, and you can barely scroll. The cells consist only of text with an opaque background, so there are no problems there.
I am sure that I am not doing it right and that there should be a better way. Thanks for your help in advance.
Mason wolters
source share