I am displaying dynamic images recieved from server in a horizontal collection view. When I set up the collectionview I set this:
-(void)setupCollectionView{
[self setupPageControlView];
self.screensCollectionView.delegate=self;
self.screensCollectionView.dataSource=self;
[self.screensCollectionView registerNib:[UINib nibWithNibName:@"FGAppScreensCollectionViewItemCell" bundle:nil] forCellWithReuseIdentifier:@"screenCell"];
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[flowLayout setMinimumInteritemSpacing:0.0f];
[flowLayout setMinimumLineSpacing:0.0f];
[flowLayout setItemSize:CGSizeMake(165, 255)];
//[self.screensCollectionView setPagingEnabled:YES];
[self.screensCollectionView setCollectionViewLayout:flowLayout];
}
For cellForRowAtIndexPath I download the image like this:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"screenCell";
FGAppScreensCollectionViewItemCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[self.imageURLArray objectAtIndex:indexPath.row]]];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
[spinner setFrame:CGRectMake(50, 100, 20, 20)];
[cell.contentView addSubview:spinner];
[cell.screenImageView setImageWithURLRequest:urlRequest placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
//STOP THE SPINNER
for (UIView* view in [cell.contentView subviews]) {
if ([view isKindOfClass:[UIActivityIndicatorView class]]) {
[view removeFromSuperview];
}
}
cell.screenImageView.image = image;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
//
}];
[cell.screenImageView setImageWithURL:[NSURL URLWithString:[self.imageURLArray objectAtIndex:indexPath.row]]];
if (self.delegate) {
UITapGestureRecognizer* g = [[UITapGestureRecognizer alloc] initWithTarget:self.delegate action:@selector(showPopUpImageView:)];
[cell.screenImageView addGestureRecognizer:g];
}
return cell;
}
However there are both portrait and landscape images displayed in the collection view. Portrait Images are displaying just fine but landscape images are appearing to small in the collectionview. What I need to do is resize the cell according to the image size so that they fill up correct aspect ratio?
I added method like this below but the problem is it gets called for all cells at once in the beginning and won't be called once I download the image in cellForRowAtIndexPath method:
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(165, 255);
}
Hence, I am wondering how can I achieve this feature, Let me know if more information is needed in this regard?
In -setImageWithURLRequest:...
, when the image loads cache it in a hash table, and then call -reloadItemsAtIndexPaths:
with the current image path, to reload the cell and thus causing the CollectionView to re-check what size the cell should be.
Make sure you consult the hash table when looking up the image. This will also save you extra network accesses in cases where the collectionView items scroll offscreen and back on again.
Note I am worried that if you’re using a UICollectionReusableView
subclass your code can fail, because cells can be re-used before their images ever load, so the images will load in the wrong place.
However add an delegate method of UICollectionView.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[arryOfImg objectAtIndex:indexPath.row]]];
//You may want to create a divider to scale the size by the way..
return CGSizeMake((image.frame.size.width)/4.0, (image.frame.size.height)/4.0);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With