sdwebimage: Image in table cell gets stretched after initial load - iphone

I am using SDWebImage in my iPhone project and I use it to load images to my table cell.
The original downloaded image 150 * 150.
My placeholder image is 32*32 (required size)
First time, when the image loads, sdwebimage does a great job of re-sizing the downloaded image to match the size of the placeholder image (32*32). All good.
However, when I navigate back and then come back to the same page, the image gets stretched and fills the entire cell.imageView height. Is this normal behavior?
I need it to always retain the initial 32*32 size. Can you suggest how to do that?
EDIT: I found this link where another user faces a similar issue (question open). The user also made a short youtube video to explain the issue.
Thoughts?

try that for specific size at the cellForRowAtIndexPath :
UIImageView *addImage = [[UIImageView alloc] init];
[addImage setImageWithURL:[NSURL URLWithString:yourCellImageURL] placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
[addImage setFrame:CGRectMake(7, 3, 78, 57)];
[cell.contentView addSubview:addImage];
[cell setIndentationLevel:8];

tldr: If your custom UITableViewCell subclass has a #property IBOutlet UIImageView* called imageView, change your name to something else (such as customImageView) and it will work properly. Read the rest of the answer for why
I see nobody has answered that, and I wasted a whole week trying to find the solution to this, so here's what happened to me, and how to prevent it happening to you (thus fixing your problem).
I created a CustomTableViewCell which extends UITableViewCell.
I added #property (weak, nonatomic) IBOutlet UIImageView *imageView; to my custom cell.
Everything seems fine until now, right?
Except it is not.
UITableViewCell already has an imageView property. iOS 7 uses your property at first, but then when the Cell is being reused, the UITableViewCell's imageView is used, therefore ignoring all of your constraints or previously defined fixed sizes.
iOS 8 always uses the image from UITableViewCell. so the problem is more obvious there. Previous iOS versions also had varying degrees of this problem, usually presenting very similar symptoms.
The solution? Either deal with the property UITableViewCell.imageView by yourself (add code for laying out the view) or create your own property with a different name, with which you can add constraints (in case you're using auto layout) on Storyboards or xib.

Try to set proper content mode of the UIImageView

if you want to change image size in SDWebImage.
use this call.
// Here we use the new provided setImageWithURL: method to load the web image
[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) { /*here you can change size of image */ }];

Related

Issues setting up a back ground image and with UIImageView

On my iPhone app, I simply want to set a particular background image, which depends on whether it's an iPhone 5 or not.
So, I tried two approaches:
A) Using
self.view.backgroundColor = [UIColor colorWithPatternImage:backGroundimage];
B) Creating an UIImageView and setting up the image there. Code:
UIImageView *backgroundImageView = [[UIImageView alloc]initWithFrame:screenBounds];
[backgroundImageView setImage:[UIImage imageNamed:backGroundImage]];
[self.view addSubview:backgroundImageView];
But I am having issues with both of them:
Issues with Step A:
When I set the image through that way, I have to deal with the image scaling issues for different sizes of the screen. I use the following code to do the scalling:
UIGraphicsBeginImageContext(screenBounds.size);
[[UIImage imageNamed:backGroundImage] drawInRect:screenBounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.view.backgroundColor = [UIColor colorWithPatternImage:image];
Another issue from Step A is that the image appears quite blurry. It doesn't have the same sharpness to it.
Issues with Step B:
With this, the image looks really crisp and sharp - just the way it should look.
But when I switch to another view using the following code, strangely enough the UIImageView backgroundImageView still appears on the second one. The code I use to switch views is:
[self presentViewController:secondViewController animated:YES completion:nil];
I even tried [backgroundImageView removeFromSuperview], but that doesn't solve anything either.
So what am I doing wrong? And how can I set up a picture as my background which is dependent on the size of the iphone?
Plan B is a good plan. Presenting another view controller should and will definitely hide your image view. If it isn't happening, then it's a problem with the creation of secondViewController, unrelated to the background image on the presenting VC.
Before presenting secondViewController, log it:
NSLog(#"presenting %#", secondViewController);
I'll bet a dollar that it's nil. If I'm right, let's have a look at how you initialize secondViewController. That's the problem, unrelated to the background image view.
Okay, I finally fixed this issue, although the cause of this issue is still puzzling to me.
To fix this, I had to create an IBOutlet property for UIImageView and hook it up on the XIB file.
The reason I was programmatically creating the UIImageView is because the size of the UIImageView depends on what size iPhone they are using. But for the IBOutlet (let's call it as UIImageViewOutlet, I simply used [self.UIImageViewOutlet setFrame:] to get the size and location that I wanted.
I also discovered that one of the buttons that I was programmatically creating, was still visible in the secondViewController. I ended up creating an Outlet on the XIB file for that one as well and used setFrame on it to position it properly.
If anyone who knows the reason of this problem, I will be very grateful.

SDWebImage - how to load image from Cache?

I use SDWebImage to download images into my UITableView using:
[cell.imageView setImageWithURL:[NSURL URLWithString:tempPhotoURL] placeholderImage:[UIImage imageNamed:#"temp.jpg"]];
This works perfectly - no problem there. But when I click on any given row in my TableView, I want to load that row's thumbnail-image into a UIImageView that's sitting in the oncoming detail-screen to which I'm navigating. Well how do I do this? Do I now have to get the image from the cache since its already been downloaded? If so, what's the method/process for this? And if that's not the way to go, what is?
I can't figure it out from all those files and methods included in the SDWebImage library...
Simply use almost exactly same code to set the image - SDWebImage will check if it is already cached and if so, it will use it instead of fetching image from the url.
Try this,
[self.imgView sd_setImageWithURL:[NSURL URLWithString:imageUrl placeholderImage:placeholderUrl options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
//Progress block
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL){
//Completion block
}];
There are many ways to achieve things when coding.
One that springs to mind is to ensure the UIImageView is an accessible property of your detail view controller (part of the detail view controller's API).
Then all you need to do is before you push your detail view controller, assign the cell's image view to the detail view's UIImageView property.
OR
create a convenience initialiser and pass the cell's imageview to it...
etc etc.
Call the same method, you downloaded with in your TableView in DetailView when you set the picture, it will check the cache first. Here's the code snippet to download image with SDWebImage
[yourImageView sd_setImageWithURL:[NSURL URLWithString:yourImageUrl]
placeholderImage:[UIImage imageNamed:#"placeholder.jpg"]];

UIImage in uitableViewcell slowdowns scrolling table

I am loading image with data in my table view. Images are coming from web. I created method to get image url in model class.Model class has Nsdictionary and objects.
But this images is slowing down scrolling .Here is my code
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",
[(Tweet *)[recentTweets objectAtIndex:indexPath.row]urlString]]]]];
cell.imageView.image = image;
Please tell Where I am going wrong?
Use lazy loading and do your own drawing. Try to understand the techniques on the sample projects I linked. These are the best ways to improve the performance of tables with images.
here is the methodology I use for loading images into a UITableView from a remote location:
in your .h file, declare a mutable dictionary for storing the images:
NSMutableDictionary *images;
initialize the dictionary in -init... or in -viewDidLoad
images = [[NSMutableDictionary alloc]init];
in the .m, tableView:cellForRowAtIndexPath:, see if the image exists in your dictionary for the indexPath
UIImage *img = [images objectForKey: indexPath];
if the image does exist, just set it.
if (img) cell.imageView.image = img;
if the image does NOT exist, set the cell's image to a temporary image...
if (!img) cell.imageView.image = [UIImage imageNamed:#"imageUnavailable.png"];
AND add that image to your dictionary so it doesnt try to refetch the image if you scroll off and back to that image before it loads...
[images setObject:[UIImage imageNamed:#"imageUnvailable.png"] forKey: indexPath];
then, in this same block, use an NSOperationQueue, and a custom NSOperation ( here is a reference - NSOperation and SetImage) to get your image and call back into your UITableViewController with that image.
in your callback, add your image to the dictionary (overwriting the temp image) and call [tableView reloadData]
this will give you a nice non blocking user experience.
The are a couple of ways how to do it. I had the best experience with a Queue for the HttpRequests, which I pause during the scrolling process.
I highly recommend this framework for that:
http://allseeing-i.com/ASIHTTPRequest/
I also implemented an image cache, which only loads the images if there weren't in the cache.
And the last tweak was to actually draw the images instead of using a high level uicomponent like the UIImageView
The number one reason your code is slow right now is because you're making a network call on the main thread. This blocks an UI from being updated and prevents the OS from handling events (such as taps).
As already suggested, I recommend ASIHTTPRequest. Combine asynchronous requests with an NSOperationQueue with a smaller concurrency count (say, 2) for the image requests, caching, and reloading the rows when images come in (on the main thread) (also only reloading the row if its currently visible). You can get a smooth scrolling table view.
I have an example of this on github here: https://github.com/subdigital/iphonedevcon-boston
It's in the Effective Network Programming project and includes a set of projects that progressively improve the experience.
Download the images before you load the tableView, and store them in an NSArray. Then when the cellForRowAtIndexPath method is called, show a loading image until the image is in the array.

UIImageView with stretchableImageWithLeftCapWidth doesn't stretch image

I'm trying to stretch an Image in a UIImageView - but I fail miserably :)
Following setup:
NIB-File with a view and a UIImageView attached to this view.
Wired to my class using IBOutlet UIImageView *background.
Now, in my class I try the following:
UIImage *bgImage = [[UIImage imageNamed:#"myImage.png"] stretchableImageWithLeftCapWidth:0 topCapHeight:50];
[background setImage: bgImage];
bgFrame = CGRectMake(0, 0, 250, 200);
background.frame = bgFrame;
which should stretch the image vertically - at least, that's what I thought. Alas, it's not working... :(
The image I'm using has a height of 115px (which should be enough for the stretch, I guess?)
Got it... (interesting that this happens often just seconds after asking the question)
In IB, I had to set the mode in the UIImageView to «Scale to fill» and set the Autoresize-property
That's what solved the problem...
Hope that helps somebody ;)
Sometimes it depends on the file, However I did two things to fix it and I don't know which was the solution:
Open and resave the file (I don't think this made the difference)
Create the file.png and file#2x.png file. (Anyway this should always be done with stretchable images)
After I added the #2x file the image stretched ok.

UIButton with image losing its newly set image

I've got a UIButton (custom, with image) set up in IB which is an IBOutlet in my code.
In my viewDidLoad method in the viewController, I am trying to change the existing image of the UIButton
UIImage *newbuttonimage = [UIImage imageNamed:#"newbuttonimage.png"];
testbutton.imageView.image = newbuttonimage;
OK, that works when starting the app, but whenever you interact with the button (press it), it changes to the original image (set in IB). There's no other code to change images in the whole project, so what is going on?
Incidentally, when I put the above code in any other part of my project it doesn't change the image.
You should try using setImage:forState instead of assigning the image directly; there are multiple states of a UIButton and, if not set properly, may yield unwanted behaviors (akin to the ones you're seeing).
Doh! I should have used this code instead:
UIImage *newbuttonimage = [UIImage imageNamed:#"newbuttonimage.png"];
[testbutton setImage:newbuttonimage forState:UIControlStateNormal];