UICollectionView showing wrong cells after scrolli

2019-02-12 01:24发布

I have a UICollectionView within a UIViewController. In the collectionView cellForItemAtIndexPath: method, it creates a series of custom cells based on the datasource. The custom cells in turn contain a UIView, subclassed to draw single PDF pages.

It's set up in such a way as to split a PDF file into its single pages, so cell 1 contains PDF page 1, cell 2 contains PDF page 2 and so on. So far so good, here's my problem:

When I scroll down, the UICollectionView starts displaying the wrong cells. For instance in a 34 page document, it shows cells/pages 1-16 in the correct order, but then starts displaying pages that seemed to have been dequeued further up, such as cell 1, cell 2, cell 4. I never get anywhere near cell/page 34.

I've seen similar behaviour from UITableView in the past, and believe it has something to do with the dequeueing of the cells, or a delegate method. Not quite sure - any help is appreciated.

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

//create custom cell
CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellID" forIndexPath:indexPath];

//set file name (always the same; one PDF file)
cell.fileName = fileName;
cell.backgroundColor = [UIColor clearColor];

//set the title to the page number
cell.title = [NSString stringWithFormat:@"page %@", [countArray objectAtIndex:indexPath.row]];

//set the current page (which indicates which page to display) according to the pageCount
cell.currentPage = [[countArray objectAtIndex:indexPath.row] intValue];

return cell; }

3条回答
放荡不羁爱自由
2楼-- · 2019-02-12 01:48

I've had similare issues. This is most likely because the reused cells do not redraw themselves. In your custom cell's content class (your PDF view), trigger redrawing if the frame is updated:

-(void)setFrame:(CGRect)frame {
    [super setFrame:frame];
    [self setNeedsDisplay]; // force drawRect:
}

This worked for me. In addition, if your cell size may change, set the autoresizing mask so that it fills space with

self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

during initialization.

查看更多
Emotional °昔
3楼-- · 2019-02-12 01:58

I fixed a similar issue in swift based on Asatur Galstyan's answer.

After associating a custom class to a cell in a storyboard the prepareForReuse() function can be overriden:

import UIKit

class SomeCollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var exampleView: UIView!
    @IBOutlet weak var exampleLabel: UILabel!

    override func prepareForReuse(){
        super.prepareForReuse()
        exampleLabel.textColor = nil
        exampleView.backgroundColor = nil
        exampleView.layer.cornerRadius = 0
    }
}

There default implementation of prepareForReuse() does nothing (at least in iOS 10) but Apple recommends calling the the super.prepareForReuse() when overriding anyway.

查看更多
\"骚年 ilove
4楼-- · 2019-02-12 02:05

Fixed similar issue using prepareForReuse method

just add this method to your custom cell implementation

- (void)prepareForReuse {

     self.fileName = nil;
     self.title = nil;

     // add remaining properties 

}
查看更多
登录 后发表回答