问题
I'm building a UICollectionView and my custom cells will contain two labels and one image.
Each image is downloaded asynchronously so I don't know it's size until the download it's complete. Once is downloaded, I want to adapt each cell to re-layout it's content and frame to fit in height the image just downloaded.
As UICollectionViewLayout, I'm using CHTCollectionViewWaterfallLayout
To download the image asynchronously I'm using SDWebImage, like this:
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
{... some completion code here ...}];
QUESTION:
What is the right approach to resize each UICollectionViewCell right after the image is downloaded?
回答1:
You should just be able to invalidate your collection view layout in an animation block when the image comes back. Things might get a little complicated if more than one image finishes completion at once, but this should work:
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)^{
[UIView animateWithDuration:0.3f animations:^{
[self.collectionView.collectionViewLayout invalidateLayout];
}];
}];
Then just return a different size in the appropriate delegate method.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return /* a different size if the image is done downloading yet */;
}
回答2:
To resize collection view cells, you could reload the collection view and return the size of you collection view cells dynamically in the method:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
return [cell size];
}
In cases when the cell's size is dynamic, get the cell from the index path and return its size based on the size of the image. I usually create a method for the cell to return a dynamic size, like in the example above. You can use UIImage's size property to help return the size based on the image.
回答3:
You could try to reloadItemsAtIndexPaths: for the cells that finished loading.
来源:https://stackoverflow.com/questions/23121663/resize-uicollectionview-cells-after-image-inside-has-been-downloaded