2

So I have a UICollectionView with a different image of different size in each cell. When cellForItemAtIndexPath: is called, I update the UICollectionViewCell with a method that fetches an image asynchronously on the web and displays it full size.

My problem is the size of my cell is already set prior with sizeForItemAtIndexPath. I would like it to be recalled so the cell has the downloaded image size.

How can I do this?

Michael Eilers Smith
  • 8,466
  • 20
  • 71
  • 106
  • Can you add your code of **"method that fetches an image asynchronously on the web and displays it full size"** ? – Avt Mar 09 '14 at 18:23

1 Answers1

4

If you have already set up your sizing, find the index of the cell you'd like to refresh:

NSIndexPath * indexPathOfCellToResize = // index path of cell to refresh
[myCollectionView reloadItemsAtIndexPaths:@[indexPathOfCellToResize]];

There's probably a better way to do this, but here's something that works:

Create A Delegate Protocol In Your Cell

@protocol CellDelegate

- (void) imageIsReadyForCell:(id)cell;

@end

Delegate Property

@property (strong, nonatomic) id<CellDelegate>delegate;

In Cell, when image finished call:

[self.delegate imageIsReadyForCell:self];

Then in your file hosting the collectionView in interface

@interface SomeViewController : UIViewController <CellDelegate>

And in the .m

- (void) imageIsReadyForCell:(id)cell {
    NSIndexPath * indexOfReadyCell = [yourCollectionView indexPathForCell:cell];
    [myCollectionView reloadItemsAtIndexPaths:@[indexPathOfReadyCell]];
}
Logan
  • 52,262
  • 20
  • 99
  • 128
  • will this call sizeForItemAtIndexPath? And if so, how can I access the updated cell so I can get the imageView size? – Michael Eilers Smith Mar 09 '14 at 18:08
  • Yes, it should recall everything. I'm updating with a method that I've used. – Logan Mar 09 '14 at 18:10
  • Awesome. But I still need to provide sizeForItemAtIndexPath with the size of the cell's image. Is there a clean way of doing that? – Michael Eilers Smith Mar 09 '14 at 18:27
  • Assuming your images are already appropriately sized they come with a size property, img.size – Logan Mar 09 '14 at 18:28
  • So my guess would be that I have to store the size property in a dictionary when imageIsReadyForCell is called so that sizeForItemAtIndexPath can use it later on. What do you think? – Michael Eilers Smith Mar 09 '14 at 18:29
  • 1
    That's one way, or in sizeForItem: YourCustomCell * cell = [myCollectionView cellForItemAtIndexPath:indexPath]; return cell.yourCustomCellImageProperty.size; – Logan Mar 09 '14 at 18:32
  • hmmmm that might create an infinite loop though. I fetch my image in cellForItemAtIndexPath:indexPath. – Michael Eilers Smith Mar 09 '14 at 18:34
  • I can't cite anything in particular, but you probably shouldn't do it that way. I'd suggest moving that. – Logan Mar 09 '14 at 18:37
  • Yes, anytime you scroll or adjust your collection view, that method will run. It really shouldn't contain any heavy code. Good luck with the rest of your app! – Logan Mar 09 '14 at 18:39
  • Well at least I cache the image... The thing is I don't see where else I should load the image. There's no point in loading all the images if the user isn't going to scroll all of them. – Michael Eilers Smith Mar 09 '14 at 18:40
  • In the past, I've done it within the cells themselves. Asynchronous image loads on collectionviews get tricky in general because by the time their data arrives the cell might be repurposed with different data. Also, I'm not the end authority on code, so if you've found a solution that's working for you that isn't causing memory or performance constraints, who am I to tell you not to! – Logan Mar 09 '14 at 18:43
  • within the cell? I'm not sure what you mean. Can you give me a quick example? – Michael Eilers Smith Mar 09 '14 at 18:44
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/49363/discussion-between-logan-and-omegatai) – Logan Mar 09 '14 at 18:47