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?
Related
This question is for my understanding as my code is working fine.
I have looked inside SDWebImage, but it's fairly large and I can't pinpoint how the mechanism I'm questioning works.
OK, let's say I have a tableview full of UIImageViews (one inside each cell), and I call the SDWebImage Category/Extension on each of them to go and lazy load an image from the web.
What mechanism is employed to update the cell as it's on screen with the newly downloaded image, without reloading the tableview?
I ask this as I was surprised to see that when using SDWebImage Extension each of my cells' imageViews image popped into existence as soon as it's corresponding image had downloaded.
I was under the impression that I'd have to reload the tableView, but instead each cells imageView 'automagically' updated when the image was available!
How does this work? Does SDWebImage keep a reference to each cell/imageView it's working with?
SDWebImage inserts the loaded image into the UIImageView instance on which the load has been queried.
With UITableViewCell you have to be a bit tricky to avoid non-relevant images in your cells, here is why:
Imagine you requested the image for URL of the first item (firstURL) on the topmost visible cell.
You scroll down your table, and following happens:
the former topmost cell gets reused and appears on the bottom of the table.
the image is queried for URL of the last cell (lastURL).
firstURL loading completed, and corresponding image is inserted into the image view of the last cell, because it was the image view for which firstURL loading has been queried.
lastURL loading completed, and corresponding image is inserted into the image view of the last cell.
Steps 3 and 4 might look like fast blink in the image view.
To avoid that, you need to address the cancellation of the previous download in prepareForReuse method implementation of the UITableViewCell subclass.
e.g.
- (void)prepareForReuse {
[super prepareForReuse];
[self.imageView sd_cancelCurrentImageLoad];
self.imageView.image = <placeholder image>;
}
If you are referring UIImageview in UITableviewCell then you can check that SDWebImage is one kind of UIImageView class, so no need to describe which image view refers for downloaded image, as its self identify
Let me show you once..
as we request for image inside cell like this.
[cell.imgBrand sd_setImageWithURL:url completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
}];
When first line executed, it will call method inside UIImageView+WebCache.h class.
as you can see that class itself UIImageView
#implementation UIImageView (WebCache)
Class For SDWebCache UIImageView
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.
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
}
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.
I want to load an image onto a table view cell, i.e., a custom cell with an image view. And, I use SDWebImage. I am loading an image onto the cell without using setImageWithURL. This is the code inside cellForRowAtIndexPath.
[_imgManager downloadWithURL:urlArray[indexPath.row]
completed:^(UIImage *image, NSError *error//yada, yada) {
if(image)
{
NSLog(#"Image received");
//cell.pictureView.image = image; // doesn't work, so I did
dispatch_async(dispatch_get_main_queue(), ^{
UITableViewCell *tCell = [self.tableName cellForRowAtIndexPath:indexPath];
if(tCell)
tCell.imageView.image = image;
}); // doesn't work either
}
}];
So as I have mentioned in the comments, it doesn't work. What am I doing wrong? Or maybe my conception of this is wrong? The images load only after I scroll (that activates cellForRowAtIndexPath for other cells). And they keep refreshing on each appearance. It doesn't work exactly as expected.