How to adjust cell height for picture that is downloaded async - ios

I'm setting the image of my custom cell like this.
__weak CustomCell *weakcell = cell1;
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:postPictureLink]];
//it uses AFNetwork's UIImageView+AFNetworking extension
[cell1.postImageView setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakcell.postImageView.image = image;
//this method call changes cell height according to image size
[weakcell layoutSubviews];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
}];
But then how do I implement
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
method so that it can give different heights according to size of my cell? Because of images size can vary different cells have different heights.

This is very hard to do. One option would be to somehow get the size from the API you are getting your image from.
A second option would be to only show your cell after the image is downloaded. You can then get your height from the image itself.
Lastly you could reload your rows after the image is downloaded. This might cause a few weird animation issues as your images download.

I have done the similar what you want to do, for this the APIs written will return me the size of the image with the URL, so I know how much size it going to take when dowloaded from server so I give the height according to that.If you see flickr or any other APIs for images you can see there is an option to get the size of the each different resolution image.

Keep in mind that your table view cells can (or should) be reused with the dequeueReusableCellWithIdentifier: method, so you don't want to store the images on the table cells.
A better solution would be to maintain an array of images that you can query in heightForRowAtIndexPath, as well as using it when you configure the actual cells.

Related

Handle loading & refreshing on a CollectionView Objective-C

I am building an Xcode application that features a vertically scrolling UICollectionView of Views with large ImageViews in them, similar to Instagram. This Collection View originally loaded very small images into the ImageViews in each UICollectionViewCell, making the app load fast and making the loading of individual cells instantaneous.
I recently made a change to the app that makes the Collection View Cells load much larger images into their Image View, which causes 2 things in some cells:
1) A wait time where the ImageView is blank until the image is loaded
2) Temporary repetition of old images in cells that have been reused from the queue while the new image is loading
Below is the code that I use to initialize my cells:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell;
NSString *CellIdentifier;
UIImageView *thumbnailImage;
CellIdentifier = #"FollowersFeed";
cell = [collectionView
dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
thumbnailImage=(UIImageView *)[cell viewWithTag:1];
dict=[follwerFeed objectAtIndex:indexPath.row];
NSString *nurl=[dict valueForKey:#"video"];
[thumbnailImage setImageWithURL:[NSURL URLWithString:nurl]];
//........
return cell;
}
In order to fix the functionality of this app with these new larger pictures, I need to solve the loading problem by
1) Showing an Activity Indicator spinning while the Image View in a Collection View loads.
2) Remove the image link from the previous Image View before the cell is reused in the queue.
I believe that if I can figure out how to do both of these, then the app's scrolling will work just as seamlessly now as it was with the smaller images
You can try https://github.com/rs/SDWebImage - Asynchronous image downloader with cache support as a UIImageView category
Easy to use:
#import <SDWebImage/UIImageView+WebCache.h>
...
[imageView sd_setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
You can try NSURLRequest
NSURLRequest *request = [NSURLRequest requestWithURL:imageUrl];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
cell.thumbnailImage.image = [UIImage imageWithData:data];
}
}];

While scrolling resize the custom Table cell height with UITableViewAutomaticDimension as per downloaded image height

I am getting the image's URL at run time and  download & display these images in a table. Images are  downloading asynchronously(using SDWebImage). What is more important is that I want to display all these images with their actual sizes. First time ,the table is loading fine, I have more than 5 section(each section contains one row) and when I scroll the table and try to update sections by using reloadSections, then the table shows with wrong cell image height. Can anybody help me out with this?
Note: I am using UITableViewAutomaticDimension
[_imageViewSharedImage sd_setImageWithURL:[NSURL URLWithString:[_popUpManager.popUpDetails valueForKey:#"photo"]] placeholderImage:[UIImage imageNamed:#"placeholderBackground"] options:SDWebImageProgressiveDownload completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)
{
UIImage *croppedImage=[Util adjustImageSizeWhenCropping:image];
[_imageViewSharedImage setFrame:CGRectMake(_imageViewSharedImage.frame.origin.x,_imageViewSharedImage.frame.origin.y,croppedImage.size.width,croppedImage.size.height)];
[_imageViewSharedImage setImage:croppedImage];
[self setNeedsLayout];
[self updateConstraintsIfNeeded];
}];
When using UITableViewAutomaticDimension, you have to specify auto layout constraints from top to bottom for all the items in your cell's content view. Hope you have done that.
And while using auto layout, you should take care to not adjust the frame. If you want to do so, do it using constraints. Make an outlet for the height constraint and width constraint of your imageViewSharedImage and set its constant to the values you require.
_imageViewHeightConstraint.constant = croppedImage.frame.size.height;
_imageViewWidthConstraint.constant = croppedImage.frame.size.width;
Then call layoutIfNeeded.

Table View Cell Height randomly not calculating some Cell Heights

I have a few Table View Cell Heights randomly not calculating some Cell Heights by the time they are on screen.
(Scrolling down)
**Only when they go off screen, and then scrolled back up to, do they calculate as needed.
(Scrolling Back up)
Has anyone ever heard of this, or know what to do?
I'm using AutoLayout, Storyboards, SDWebImage to load the images from a URL, and this code in cellForRowAtIndexPath:
__weak TableViewCellTwo *wcell = api2Cell;
[wcell.imageViewPic
sd_setImageWithURL:[NSURL URLWithString:#"http://dummyimage.com/600x600/000/fff.png"]
placeholderImage:[UIImage imageNamed:#"fff.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
// Put Log
}
];
My Storyboard:
UPDATE:
Wanted to add to my question to see if I could get an answer. Still having problems with this. Wondering if there's any way to do this without using heightForRowAtIndexPath. Is this just an iOS bug?

Table View Cell sometimes not sizing Height of cell

I have a TableView with custom cells, and for some reason there will be a Table View Cell added that doesn't calculate its height (like these two examples):
The Cell finally calculates it when I scroll down past the blank cell and then back up to where it was before, and I can see the Images "flashing" and placing themselves in the correct spot in the Table View. So I assume it has something to do with the image's in my Table View not loading immediately or something?
Seems to happen in my testing mostly when there are two Table View Cells next to each other in the Table View that have Images in them.
I've tried a bunch of different things, have you ever heard of this? Any idea how to fix? Thanks!
I'm using AutoLayout and Storyboard.
UPDATE
Per Request, adding cellForRowAtIndexPath code:
__weak TableViewCellTwo *wcell = api2Cell;
[wcell.imageViewPic
sd_setImageWithURL:[NSURL URLWithString:imageURL]
placeholderImage:nil
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
// Put Log
}
];
UPDATE
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return tableView.rowHeight; // return the default height
}

change width and height of UIImageView dynamically inside tableViewCell

I have custom UITableViewCell which made from xib file .
And I have UIImageView inside that cell which I set the fixed width and height and 40x40 and set to hidden
And then in cellForRowAtIndexPath datasource delegate. I check if my datasource for that cell contain a URL to image . If it has ,I set the ImageView to appear .And use SDWebImage to download the image and adjust the size for imageView.frame in the completion block when download complete
Actually, at first appearance it is working fine .I got the ImageView that is the same size and the downloaded image. But if I scroll down and then up to the upper cell again. It just re-appear to 40x40 size gain. Can anyone help ?
This is the code just in case if you are curious. I guess nothing wrong with the code the problem is how I set the UIImageView in .xib file but I don't know how to solve it.
// -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
if([item postImageURLString]){
void (^completionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType) = ^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
CGRect imageFrame = CGRectMake(cell.frame.size.width/3,cell.frame.size.height -5 -image.size.height, image.size.width, image.size.height);
[cell.postImageView setFrame:imageFrame];
};
[cell.postImageView setHidden:NO];
[cell.postImageView setImageWithURL:URL completed:completionBlock ];
}
I suspect it has something to do with the tableview reusing cells that have the 40x40 image view. It looks like SDWebImage will not run your completion block if the image is already cached, so if the tableview redraws the cell and your image is already cached, it never executes the resizing code. You need to add code to your cellForRowAtIndexPath method that checks to see if the image is already cached, and if it is then resize the image view.

Resources