Images display on UITableViewCell - ios

I am trying to display images in UITableViewCell, I'm using web service to get the image names. Here is what i'm getting in the response of web service.
"2514466130834f61a9g38d57h0e2cb-25-ProfilePic.PNG",
"26144482598634297156heb8c0dafg-26-ProfilePic.PNG",
"2714464392629h60253gd4ec8b1f7a-27-ProfilePic.PNG",
"2814449113316a7gh5db0e2139c84f-28-ProfilePic.PNG",
"2914454043856e3519ah0dbf27cg84-29-ProfilePic.PNG"
The above response is saved in the array format. These array objects are then append on a url, And I need to display images on UIImageView.
Please Help me.

Prepare your url like below.
// Consider this is your prefix url
NSString *urlPrefix = #"https://your_url_prefix/"; // like http://stackoverflow.com/
// Consider this is the array you parsed from the web service
NSArray *resourceArray = #[#"2514466130834f61a9g38d57h0e2cb-25-ProfilePic.PNG", #"26144482598634297156heb8c0dafg-26-ProfilePic.PNG", #"2714464392629h60253gd4ec8b1f7a-27-ProfilePic.PNG", #"2814449113316a7gh5db0e2139c84f-28-ProfilePic.PNG", #"2914454043856e3519ah0dbf27cg84-29-ProfilePic.PNG"];
Prepare the resource url in your tableView's data source method: cellForRowAtIndexPath
NSString *resourceURL = [urlPrefix stringByAppendingString:[resourceArray objectAtIndex:indexPath.row]];
and use SDWebImage library to load the image and set that in to your cell imageView like
[cell.imageView setImageWithURL:resourceURL];
Note: SDWebImage lib can be downloaded from SDWebImage Git
Add this library files in your project and import like below to use.
#import "UIImageView+WebCache.h"

First download Asynchronous Class Here
Then put your .m file
#import "AsyncImageView.h"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpletableidentifier=#"simpletableidentifier";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:simpletableidentifier];
if(cell == nil)
{
cell.backgroundColor=[UIColor clearColor];
cell = [[UITableViewCell alloc ]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpletableidentifier];
}
AsyncImageView *Galleryimg = [[AsyncImageView alloc]initWithFrame:CGRectMake(0,0,40,40)];
Galleryimg.contentMode = UIViewContentModeScaleAspectFill;
Galleryimg.clipsToBounds=YES;
Galleryimg.tag=i;
Galleryimg.imageURL=[NSURL URLWithString:[Yourstring stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[scroll addSubview:Galleryimg];
return cell;
}

Related

Download array of images and play on table cell in objective c

How can I download set of images from server and display those images inside table cell. Could you help with completion block or delegate. Example will be really appreciated.
[tableCell.playerView addSubview:imagePlayerView];
dispatch_async(dispatch_get_main_queue(), ^{
[imagePlayerView downloadImages];
});
It's not a good way to add subview imagePlayerView in cellForRowAtIndexPath, because on reload it will again create and load, so use custom cell for arranging view.
// Not a good way to do that
[tableCell.playerView addSubview:imagePlayerView];
Create a custom cell for your table view with UIImageView on cell. Refer the link https://www.appcoda.com/customize-table-view-cells-for-uitableview/
In your view controller class:
Follow the below steps:
Import AFNetworking+UIImageView in your view controller file
Update cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static cellIdentifier = "cellidentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
NSURL *url = [[NSURL alloc] initWithString:"Your Url"];
[cell.imageProfPic setImageWithURL:url]; // Supposing "imageProfPic" is the UIImageView in your cell's custom class
return cell
}

Setting image in custom uitableviewcell causes lag

I have a uitableview where I use a custom cell. However, when I scroll the table view there is some serious lag. It happens when I set the UIImaveView's image property with an image. I am accessing an image from the directory. But since file IO is slow I am using the dispatch_async to load the image into a UIImage object on a separate thread.
However there is still some lag. When I scroll up and down the rows without any images, the scrolling is very smooth. However when the row actually has an image, there is lag. the momentum scrolling will halt, then the app becomes unresponsive, then when the image finally loads the momentum continues where it left off.
I am not sure what is causing the lag. At first I thought it had to do with the image being too large so i tried scaling it down. Still lags. Again, if I don't set the image in the custom cell there is no lag. But when I do set it there is lag. I am not sure how to fix this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DHTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kReuseIdentifierGoalCell forIndexPath:indexPath];
[self configureCell:cell forIndexPath:indexPath isForOffscreenUse:NO];
return cell;
}
- (void)configureCell:(DHTableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath isForOffscreenUse:(BOOL)offscreenUse {
if (cell == nil) {
return;
}
[cell setDelegate:self];
PATH_TO_FILE = SQLITE_QUERY_TO_GET_PATH; //some pseudo codes
__weak typeof(sSelf)wSelf = sSelf;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__strong typeof(wSelf)sSelf = wSelf;
UIImage *unscaled_image = [UIImage imageWithContentsOfFile:PATH_TO_FILE];
UIImage *image = [unscaled_image imageScaledToFitInSize:kCellUIImageSize];
__weak typeof(sSelf)wSelf = sSelf;
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(wSelf)sSelf = wSelf;
DHTableViewCell *cell = (id)[sSelf.tableView cellForRowAtIndexPath:indexPath];
if (cell) {
[cell.imageStored setImage:image]; //Commenting this out relieves all lag
}
});
});
}
#Calimari328 I hate if to put this as an answer because it does not really answer your question but the truth is what you should really do is use a library to achieve this. for example SDWebImage
Example:
#import <SDWebImage/UIImageView+WebCache.h>
...
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// 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"]];
cell.textLabel.text = #"My Text";
return cell;
}
You have to rethink this, cells get reused, that means each time you scroll your app will try to download images again.What about performance? memory ? cache ? processing?
As you think more about it is a lot more complex then a simple async task. Fortunately there are opensource projects to achieve this. No need to reinvent the wheel.
Please note I am not advertising any library if you want to write your own code you can do this as well. You can also search on the web for easy ones to implement.

Async image loading from url inside a UITableView cell - wrong image while scrolling

I had an IPhone application in which i am loading images asynchronously from an array ,using this in cellforrowatindexpath,
` - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
sCell *cell = (sCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[sCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSMutableDictionary *dicttable=[sarray objectAtIndex:indexPath.section];
NSString *icon= [dicttable objectForKey:#"thumb_image"];
cell.image.image = [UIImage imageNamed:#"thumbnail-default.png"];
if(icon.length!=0)
{
if(![[ImageCache sharedImageCache] hasImageWithKey:icon])
{ cell.image.image = [UIImage imageNamed:#"thumbnail-default.png"];
NSArray *myArray = [NSArray arrayWithObjects:cell.image,icon,#"thumbnail-default.png",[NSNumber numberWithBool:NO],nil];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate performSelectorInBackground:#selector(updateImageViewInBackground:) withObject:myArray];
}
else
{
cell.image.image = [[ImageCache sharedImageCache] getImagefromCacheOrUrl:icon];
}
}`
and all working fine,Because i enabled paging i need to call the request to load the next set of values, like this
`- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.section==[sarray count]-1)
{
[self performSelectorInBackground:#selector(loadingfeedcntents:) withObject:count];
}
}`
but here the problem is when i am scrolling the table view wrong images are assigned to the image views in the custom cell,Can anybody help me on this ?
This is most probably due the reuse of the cells. Probably what is happening is that you trigger an asynchronous request to download an image, while that is happening you scroll the table an that cell is reused so when the image finishes downloading that new cell gets the image instead of the one originally requested it.
I think you will have to find another way to do it or detach that request from the cell on prepareForReuse
Many people is recommending this class "SDWebImage" for that situation (although I haven't test it)
I have been using SDWebImage for last 2 years and have used in 5 apps, Really easy and I would say it is the best way to load images in background with caching.
Please give a try. You will love it.
A nice tutorial is here.

How to load tables of information faster using GCD

Currently I am loading all of my UITableViewControllers with images and text. I'm not sure if there is a way of shortening my loading times. I'm thinking that GCD might be the best route to go, however, I'm not too sure that I'm using this correctly:
dispatch_async(dispatch_get_main_queue(), ^{
[some method];
});
This is being loaded in the ViewDidLoad, and I'm unsure if this is the correct place to use GCD. Also, is this correct way of asynchronously loading information?
use this, it downloads multiple files in different threads.And its asynchronous.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//load image here
});
If you want to load all images ,even the images which might be very down in tableView (say image at 20th row).Then viewDidLoad is perfect approach, or if you want to only load images that are currently to be shown, then download images in cellForRow:atIndexPath method.
OR,you can use AFNetworking to download multiple files much efficiently.
Hope this helps
For loading images faster in table view cells you can use SDWebImage.
It is very simple to use. Just import the SDWebImage folder into your Xcode project. It contains a category on UIImageVIew. So on any imageView object just call the method setImageWithURL as illustrated below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// 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"]];
cell.textLabel.text = #"My Text";
return cell;
}

Large Images Crashing UITableView app

So I've been searching for an answer to this and still am unable to figure it out. I have an array that contains 15 images or so I'm trying to display using a subview in a UITableViewCell. Code below - everything I've read mentions using autorelease/release to fix the issue, but I simply get ARC errors when attempting to do that. Any help would be much appreciated.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
int countthis = indexPath.row;
NSString *image = imgarr[countthis];
UIImageView *iv = [[UIImageView alloc] initWithFrame:(CGRect){.size={320, tableView.rowHeight}}];
iv.image = [UIImage imageNamed:image];
cell.imageView.image = iv.image;
return cell;
}
Large files tend to cause problems, no matter what your domain. Specifically, Apple says:
You should avoid creating UIImage objects that are greater than 1024 x 1024 in size.
It looks like you're trying to resize the image, but UIImages are immutable. So your allocated UIImageView serves only to waste processor cycles.
If you're stuck with big images that need to be scaled down, consider scaling before you assign them to the cell. You might find these routines useful: The simplest way to resize an UIImage?
Re autorelease/release: those have been deprecated since ARC. Your code doesn't appear to be leaking memory. I wouldn't sweat it. But you should edit your question to include details about the crash.
Your code can be cleaned up to this, which may help slightly with performance. You don't need to convert the indexPath.row to an int, since it's already a NSInteger, which is an architecture dependent type (int for 32-bit, long for 64-bit). You also probably want to use self.imgarr since its probably a property in your class. The image changes are as Neal mentioned.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString *image = self.imgarr[indexPath.row];
cell.imageView.image = [UIImage imageNamed:image];
return cell;
}
As for autorelease/release, you mentioned you're getting ARC errors using them, which indicates you're on the iOS 5 or higher SDK. They are no longer needed in your code.
You can try to resize images using CGImageSourceCreateThumbnailAtIndexfirst before displaying them in the tableview.
If you have the path to the image you want to resize, you can use this:
- (void)resizeImageAtPath:(NSString *)imagePath {
// Create the image source (from path)
CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef) [NSURL fileURLWithPath:imagePath], NULL);
// To create image source from UIImage, use this
// NSData* pngData = UIImagePNGRepresentation(image);
// CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)pngData, NULL);
// Create thumbnail options
CFDictionaryRef options = (__bridge CFDictionaryRef) #{
(id) kCGImageSourceCreateThumbnailWithTransform : #YES,
(id) kCGImageSourceCreateThumbnailFromImageAlways : #YES,
(id) kCGImageSourceThumbnailMaxPixelSize : #(640)
};
// Generate the thumbnail
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
CFRelease(src);
// Write the thumbnail at path
CGImageWriteToFile(thumbnail, imagePath);
}
More details here.

Resources