Collection View,with custom layouts, cells misbehave on scrolling

强颜欢笑 提交于 2019-12-31 05:12:14

问题


I am trying to create custom tiled layout using UICollectionView. It renders perfectly as desired in simulator once I run my app.

But the moment I scroll the view and bring it back all the cell's frame changes and the cells get overlapped, leaving spaces, randomly.

I am not able to solve this issue past 2 days. Here goes the code from my custom layout class.

-(void)prepareLayout{
[self createCellSizeArray];//cellSizeArray holds cell sizes for all the cells(calculated statically) 
[self createAttributeArrayOfAll];//attributeArrayOfAll holds attributes for all the cells and also calculates their frames using cellSizeArray
}

-(CGSize)collectionViewContentSize{
   return CGSizeMake(768, 1500);//The size is static to check for scrolling, is this creating problems?
}

-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
      UICollectionViewLayoutAttributes * layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
      return layoutAttributes;
}

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    NSMutableArray *attArray =[NSMutableArray array];
    for (NSInteger i =0; i< attributeArrayOfAll.count; i++) {
    UICollectionViewLayoutAttributes * attribute = (UICollectionViewLayoutAttributes*)[attributeArrayOfAll objectAtIndex:i];
    if(CGRectIntersectsRect(rect, attribute.frame)){
        [attArray addObject:attribute];
    }
}
return attArray;
}

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
  return YES;
}

Please help, Thanks in advance.

Edit: In my [self createAttributeArrayOfAll]; I have these lines of code

CGRect frame = CGRectMake(_startNewRowPoint.x, _startNewRowPoint.y, cellSize.width, cellSize.height);
 UICollectionViewLayoutAttributes * attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
 attribute.alpha = 1.0;
 attribute.frame = frame;
 [attributeArrayOfAll addObject:attribute];

While I modified layoutAttributesForItemAtIndexPath:, to look something like this

-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
 UICollectionViewLayoutAttributes * layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
 layoutAttributes.frame = ((UICollectionViewLayoutAttributes*)[attributeArrayOfAll objectAtIndex:indexPath.item]).frame;
 return layoutAttributes;
}

Moreover, the method layoutAttributesForItemAtIndexPath: never gets called implicitly. I even tried this:

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
NSMutableArray *attArray =[NSMutableArray arrayWithCapacity:attributeArrayOfAll.count];
for (NSInteger i =0; i< attributeArrayOfAll.count; i++) {
    UICollectionViewLayoutAttributes * attribute = (UICollectionViewLayoutAttributes*)[attributeArrayOfAll objectAtIndex:i];
    if(CGRectIntersectsRect(rect, attribute.frame)){
        [attArray insertObject:[self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]] atIndex:i];
    }
}
return attArray;
}

But still the result is the same distorted set of cells on scrolling. I worked with 5 cells, first time it renders correctly, on scrolling away and then bringing it back in visible rect it gets distorted, if i scroll away again and bring it back in visible rect it renders correctly. However, when I do this with around 400 cells, once i scroll it never renders correctly. Even on reloading collection view, The cells gets distort. Please help.


回答1:


Your layoutAttributesForItemAtIndexPath: method is not setting any properties of the layoutAttributes object before returning it. It needs to set frame (or center and size).




回答2:


So finally managed a workaround!!! dequeue each cell with an unique Cell Identifier in cellForRow:

[self.summaryView registerClass:[BFSSummaryViewCell class] forCellWithReuseIdentifier:[NSString stringWithFormat:@"%@%d",CellIdentifier,indexPath.row]];
UICollectionViewCell *collectionCell = [collectionView dequeueReusableCellWithReuseIdentifier:[NSString stringWithFormat:@"%@%d",CellIdentifier,indexPath.row] forIndexPath:indexPath];

These two lines inside cellForRow worked for me, however with my collection view having around 1000 cells it increases the size of my application considerably. Lets hope apple fixes this bug asap.



来源:https://stackoverflow.com/questions/16898584/collection-view-with-custom-layouts-cells-misbehave-on-scrolling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!