Reputation: 661
When I implement UICollectionView without a custom layout object, all 16 of my reusable cells appear. That is, I have 1 section with 16 items in that section. When I create a custom layout object, only 1 cell appears. If I change # of sections to 5, then 5 cells appear. Why does the collectionView draw sections when using a layout object, and items when using the default grid???? Am I missing something?
I subclass UICollectionViewLayout here:
static NSString * const kPadLayoutType = @"gridPads";
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if(self) {
[self setup];
}
return self;
}
- (void)setup
{
self.itemInsets = UIEdgeInsetsMake(22.0f, 22.0f, 13.0f, 22.0f);
self.itemSize = CGSizeMake(125.0f, 125.0f);
self.interItemSpacingY = 12.0f;
self.numberOfColumns = 4;
}
# pragma mark _____Layout
- (void)prepareLayout
{
NSMutableDictionary *newLayoutInfo = [NSMutableDictionary dictionary];
NSMutableDictionary *cellLayoutInfo = [NSMutableDictionary dictionary];
NSInteger sectionCount = [self.collectionView numberOfSections];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
for(NSInteger section = 0; section < sectionCount; section++) {
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 frameForPadAtIndexPath:indexPath];
cellLayoutInfo[indexPath] = itemAttributes;
}
}
newLayoutInfo[kPadLayoutType] = cellLayoutInfo;
self.layoutInfo = newLayoutInfo;
}
- (CGSize)collectionViewContentSize
{
return self.collectionView.frame.size;
}
- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.layoutInfo.count];
[self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSString *elementIdentifier,
NSDictionary *elementsInfo,
BOOL *stop) {
[elementsInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
UICollectionViewLayoutAttributes *attributes,
BOOL *innerStop) {
if(CGRectIntersectsRect(rect, attributes.frame)) {
[allAttributes addObject:attributes];
}
}];
}];
return allAttributes;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return self.layoutInfo[kPadLayoutType][indexPath];
}
# pragma mark _____Private
- (CGRect)frameForPadAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = indexPath.section/ self.numberOfColumns;
NSInteger column = indexPath.section % self.numberOfColumns;
CGFloat spacingX = self.collectionView.bounds.size.width - self.itemInsets.left - self.itemInsets.right - (self.numberOfColumns * self.itemSize.width);
if(self.numberOfColumns > 1) spacingX = spacingX / (self.numberOfColumns - 1);
CGFloat originX = floorf(self.itemInsets.left + (self.itemSize.width + spacingX) * column);
CGFloat originY = floor(self.itemInsets.top + (self.itemSize.height + self.interItemSpacingY) * row);
return CGRectMake(originX, originY, self.itemSize.width, self.itemSize.height);
}
I invalidate the layout in each setter.
I am using a collectionView within my UIViewController In the viewController I register my Cell class for use in viewDidLoad and setup the following:
# pragma mark - UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 16;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
Pad *myPad = [collectionView dequeueReusableCellWithReuseIdentifier:kPadLayoutType forIndexPath:indexPath];
return myPad;
}
Upvotes: 0
Views: 585
Reputation: 5151
It seems to me your frameForPadAtIndexPath:
method would return the same frame for each item within the same section and only varies the position with the section.
Changing
NSInteger row = indexPath.section/ self.numberOfColumns;
NSInteger column = indexPath.section % self.numberOfColumns;
into
NSInteger row = indexPath.item/ self.numberOfColumns;
NSInteger column = indexPath.item % self.numberOfColumns;
might give you better results.
Upvotes: 1