IOS: LazyLoad image From Json - objective-c

i'm new on this programming language... i try to consume json from some servers, after success consume all information, now i've problem tho show "lazyload" image into tableviewcell
i use AsyncImageView to make it happen, and here my code
-(UITableViewCell *)tableView :(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NetraCell *cell =(NetraCell *)[tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell==nil){
cell=[[NetraCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
//common settings
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
cell.imageView.frame = CGRectMake(0.0f, 0.0f, 44.0f, 44.0f);
cell.imageView.clipsToBounds = YES;
///get url image from url
//NSString *path=[[[Deals_array objectAtIndex:indexPath.row] objectForKey:#"image"]objectForKey:#"thumbnail"];
////convert image into NSDATA
// NSData* imageData = [NSData dataWithContentsOfURL: [NSURL URLWithString: path]];
////read NSData Image
// UIImage* image = [UIImage imageWithData: imageData];
//////set rounded imager with NetraImage
// image=[ImageManipulator makeRoundCornerImage:image : 30 : 30];
////show image into UItableviewCell
// cell.imageView.image=image;
}
else{
//cancel loading previous image for cell
[[AsyncImageLoader sharedLoader] cancelLoadingImagesForTarget:cell.imageView];
}
cell.imageView.image = [UIImage imageNamed:#"Placeholder.png"];
cell.imageView.imageURL = [[[imageURLs objectAtIndex:indexPath.row]objectForKey:#"image"]objectForKey:#"thumbnail"];
NSString *price=[[[somearray objectAtIndex:indexPath.row] objectForKey:#"price"]objectForKey:#"formatted"];
///call image from JSOn
///draw to tableviewcell
if(price!=NULL){
cell.detailTextLabel.text= [[[Deals_array objectAtIndex:indexPath.row] objectForKey:#"price"]objectForKey:#"formatted"]; //1 draw the price
//[cell release]
}
else{
cell.detailTextLabel.text= #"Call";
}
//draw headline
cell.textLabel.text=[[Deals_array objectAtIndex:indexPath.row] objectForKey:#"headline"];
///draw image
[UIApplication sharedApplication].networkActivityIndicatorVisible=NO;
return cell;
}
this line is my path of immage
//NSString *path=[[[Deals_array objectAtIndex:indexPath.row] objectForKey:#"image"]objectForKey:#"thumbnail"];
and this is the default method to assign pic into uitableviewcell
cell.imageView.imageURL = [imageURLs objectAtIndex:indexPath.row];
but when i try this method
cell.imageView.imageURL = [[[imageURLs objectAtIndex:indexPath.row]objectForKey:#"image"]objectForKey:#"thumbnail"];
its error, the main question is
why error? is that my remote image path wrong? or my method wrong
Need your help please :) many thanks

once check for whether you are assigning appropriate imageurl to cell image url or not in your code,[[[imageURLs objectAtIndex:indexPath.row]objectForKey:#"image"]objectForKey:#"thumbnail"], and go through this,it may help for you
lazy loading of images in UITableView cell

Related

Loading url image array add to UIcollectionview

I want to load images array from Url and add to UICollectionView
Tony.pageImages =imagearray;
[Tony reloadData];
NSLog(#"imagearray%#",imagearray);
Tony is Collection view.h/m files. pageImages is NSMutableArray on the Tony.h files. The Image array display console log mean i got image array correctly
Those are Url.
but when i add code on the UICollectionView method it doesn't work
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell =
[collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
UIImageView *CollectionViewImage = (UIImageView *)[cell viewWithTag:120];
CollectionViewImage.image= [UIImage imageNamed:self.pageImages[indexPath.row]];
return cell;
}
Do i miss something ?
This is my imagearray
imagearray = [[NSMutableArray alloc]init];
for (int i = 0;i < comment.count; i++)
{
[imagearray addObject:comment[i][#"pic_url"]] ;
}
You have to implement and set the following dataSource delegate UICollectionViewDataSource in your viewcontroller:
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section {
return imagearray.count;
}
If I got it right, you need to load image from URL.
To do that simply add this code:
[CollectionViewImage.image setImageWithURL:[NSURL URLWithString:self.pageImages[indexPath.row]] placeholderImage:nil];
Or if you want to add placeholder image, just set placeholderImage:[UIImage imageNamed:#"someImageInYourAssets"];
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:self.pageImages[indexPath.row]]];
UIImage *image = [UIImage imageWithData: imageData];
CollectionViewImage.image = image;
This is solution how solve problem loading image from url,without addition frameworks such as "Heneke","AFNetworking"..etc..In Objective C Image View can't communicated with URL directly, but can using NSData as Helper Object(wrapper).

table view with images which are loaded from server in iphone

Hi I am developing IOS application. My application contains table view with image as part of my table. I am loading my image from server. It is working fine. But problem with my table view is once I scroll my table view it is start flickering my images. That mean it showing wrong image for some time after some time it shows right images. this behaviour continues when I scroll. Is there any need to explicitly call any object to nil or release some cell object or holding some cell objects. My cell for table view looks like :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"MediaContentCell";
MediaContentCell *cell = (MediaContentCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = (MediaContentCell *)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
VideoDataModel *videoData = [_mediaContentArray objectAtIndex:indexPath.row];
cell.mediaTitle.text = videoData.title;
cell.mediaSubtitle.text = videoData.shortdescription;
NSMutableArray *posters = videoData.poster;
dispatch_queue_t myQueue = dispatch_queue_create("ImageQue",NULL);
dispatch_async(myQueue, ^
{
UIImage *image;
if(!posters)
{
image = [UIImage imageNamed:#"dummyprog_large1.png"];
}
else
{
for(int index = 0 ; index < posters.count; index++)
{
PosterDataModel *posterData = [posters objectAtIndex:index];
if([posterData.postertype isEqualToString:POSTER_TYPE_LANDSCAPE])
{
image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:posterData.posterurl]]];
break;
}
}
}
dispatch_async(dispatch_get_main_queue(), ^
{
cell.mediaPicture.image = image;
});
});
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
}
Is there any one can help me for this? Need some help Thank you.
use - SDWebImage
[cell.imageView sd_cancelCurrentImageLoad];
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
I am using this framework and Its working fine for me.
cell.imageView.image = [UIImage imageWithData:yourDefaultImgUrl];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:yourServerImageUrl];
if (imageData){
dispatch_async(dispatch_get_main_queue(), ^{
UITableViewCell *updateCell = [tableView cellForRowAtIndexPath:indexPath];
if (updateCell)
updateCell.imageView.image = [UIImage imageWithData:imageData];
});
}
});
It helps you :)
It's the reuse mechanism that causes your problem
Say, if your table view has 1000 cells to display, and 5 cells are visible on the screen at a time, iOS will only create 6 UITableViewCell objects in the memory.
In your code, the image will be loaded asynchronously from the network, and then set to the [mediaPicture] belonging to the cell at an index path, but when you scroll the table view, because of the reuse mechanism, the [cell.mediaPicture] might not be correctly related to the index path anymore, and the downloaded image will be wrongly set.
You can take a look at this question about the reuse mechanism:
UITableViewCell - Understanding "reuseable"
And Amol's answer is exactly the solution for your case.

Asynchronous loading image inside uitableviewcell

Hello I am trying to use EGOImageView inside a CustomTableViewCell who i made to customize the cell. This is the code where I used the EGOImageView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString* simpleTableIdentifier = #"Albums";
CustomTableCell* cell = (CustomTableCell*)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (!cell)
{
cell = [[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
NSLog(#"Show once or more times");
}
NSDictionary* dictionary = (NSDictionary*)[self.albumCollection objectAtIndex:indexPath.row];
cell.label.text = [dictionary valueForKey:#"name"];
EGOImageView* imageView = [[EGOImageView alloc] initWithPlaceholderImage:[UIImage imageWithContentsOfFile:#""]];
[imageView setImageURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=small&access_token=%#", (NSString*)[dictionary valueForKey:#"id"], [[FBSession activeSession] accessToken]]]];
[imageView setFrame:CGRectMake(0.0f,0.0f,78.0f,78.0f )];
[cell.iView addSubview:imageView];
[imageView release];
The image on each cell loading the same image. Would it be because it reused the cell while loading the image.
I found a problem I can't think of why the problem happened. I used the graph api to grab the image https://graph.facebook.com/%#/picture?type=small&access_token=%# where the first parameter was the album id.
To make myself easy to see the problem I only used one album on the cell, no matter what album i used the same photo turned up. But when I copy the link to the browser, the actual photo url shown on the address bar with the image shown and it shown the correct photos.
Does anyone know what was wrong.
Here is example. It loads user pics from some server in background and updates cell image. Note that imageView.image is set to nil at the beginning. This is dome for the case of cell reuse so that you will have no image rather than wrong image for the time while its downloading.
One more thing to add is that, would be also good to have a cache so that it does not download images all the time. Another nice thing is to not download images in edge networks.
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"TransactionCell";
NSMutableArray *data = searching ? searchResult : dataSource;
NSDictionary *object = [data objectAtIndex:[indexPath row]];
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithIdentifier:CellIdentifier] autorelease];
}
cell.imageView.image = nil;
cell.textLabel.text = #"Your cell text";
NSString *contact = #"foo#gmail.com";
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imgData = [appDelegate addUserPic:contact];
if (imgData == nil && netStatus == ReachableViaWiFi) {
NSString *url = [NSString stringWithFormat:#"http://somehost.com/userpic/%#", contact];
imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
}
dispatch_async(dispatch_get_main_queue(), ^{
UITableViewCell *updateCell = [self.tableView cellForRowAtIndexPath:indexPath];
if (updateCell) {
if (imgData) {
[appDelegate setUserPic:contact imgData:imgData];
updateCell.imageView.image = [UIImage imageWithData:imgData];
} else {
updateCell.imageView.image = nil;
}
/* This forces the cell to show image as now
it has normal bounds */
[updateCell setNeedsLayout];
}
});
});
return cell;
}

dequeueReusableCellWithIdentifier causing problem on UIImageView

I am loading a tableView with 500 rows. The problem is that in each row there is a different picture. Or when I use dequeueReusableCellWithIdentifier, those picture are just loaded again and the real pictures I am looking for are not shown (I just have about 8 different pictures : the first 8 loaded on my screen). If I don't use the dequeureReusableCellIdentifier, all the picture are loaded. But will it slow the displaying ?
Here is the code (I am currently working on getting the picture cached) :
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCellIdentifier = #"CustomCellIdentifier";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier: CustomCellIdentifier];
NSLog(#"Launching CellForRowAtIndexPath");
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell"
owner:self options:nil];
if ([nib count] > 0) {
cell = self.profilCell;
} else {
NSLog(#"failed to load CustomCell nib file!");
}
}
NSUInteger row = [indexPath row];
NSDictionary *rowData = [listProfils objectAtIndex:row];
UILabel *nameLabel = (UILabel *)[cell viewWithTag:nameValueTag];
nameLabel.text = [rowData objectForKey:#"name"];
NSString *finalId = [NSString stringWithFormat:#"http://graph.facebook.com/%#/picture", [rowData objectForKey:#"id"]];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:finalId]]];
[profilPic setImage:image];
return cell;
}
THank you ! :)
It looks like you have an ivar profilPic that is probably an outlet that gets linked when you load a new cell nib. If that's the case, it's always going to point to the last cell that you loaded and won't change the image in the cell you've just dequeued. Instead of using an outlet, you might want to identify that custom view some other way, like a tag. So, if you set the profile pic UIImageView's tag to 100, for example, in Interface Builder, you could do something like this:
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:finalId]]];
UIImageView* cellImageView = (UIImageView*)[cell viewWithTag:100];
[cellImageView setImage:image];
Also, I just want to point out that -dataWithContentsOfURL: will load the URL synchronously on the main thread. If you're testing in the simulator on a fast connection, this will work pretty well. If, however, you are on 3G in SoHo on Friday afternoon... your app will probably start being killed by the watchdog.
I just met this problem, my solution is hold a private NSMutableDictionary to store the new images which asynchronously loaded from web before, use my identifier as key, UIImageView as Object (because I need to load the icon image first), when web image is ready, change it, When tableView dequeue return's null, I can read the original UIImage from my own cache.
Something like this.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
UIImageView *imageView = [thumbnailCache objectForKey:identifier];
if (!imageView) {
cell.imageView.image = [UIImage imageNamed:#"icon.png"];
[thumbnailCache setObject:cell.imageView forKey:identifier];
} else {
cell.imageView.image = imageView.image;
}
}
When I load the actual image from web, refresh the thumbnail cache.
asynchronously_load_image_from_web(^(UIImage *image) {
cell.imageView.image = image;
[thumbnailCache setObject:cell.imageView forKey:identifier];
});

how can load images from plist in to UITableView?

I have stored the videos and the thumbnail images of the videos in Documents folder. And I have given the path in plist. In plist I took an array and I added directories to the array.
And in the dictionary I stored the image path
/Users/srikanth/Library/Application Support/iPhone Simulator/User/Applications/9E6E8B22-C946-4442-9209-75BB0E924434/Documents/image1
for key imagePath.
for video
/Users/srikanth/Library/Application Support/iPhone Simulator/User/Applications/9E6E8B22-C946-4442-9209-75BB0E924434/Documents/video1.mp4
for key filePath.
I used following code but it is not working. I am trying only for images. I need the images to be loaded in the table in each cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
UIImageView *image2;
image2.frame = CGRectMake(0.0f, 0.0f, 80.0f, 80.0f);
image2.backgroundColor = [UIColor clearColor];
}
NSDictionary *dictOfplist = [cells objectAtIndex:indexPath.row];
NSString *path = [dictOfplist objectForKey:#"imagePath"];
NSLog("path: %#", path);
return cell;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Library";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Close" style:UIBarButtonItemStyleBordered target:self action:#selector(close:)];
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"details" ofType:#"plist"];
contentArray = [NSArray arrayWithContentsOfFile:plistPath];
cells = [[NSMutableArray alloc]initWithCapacity:[contentArray count]];
for(dCount = 0; dCount < [contentArray count]; dCount++)
[cells addObject:[contentArray objectAtIndex:dCount]];
}
I got the path of the images are from the plist.
But, how can I extract the image from the path.
The output od NSLog: is
path: /Users/srikanth/Library/Application Support/iPhone Simulator/User/Applications/9E6E8B22-C946-4442-9209-75BB0E924434/Documents/snook.jpg
How can I get the image from it and store in cell.imageView.image ?
How can I make this work.
Thank you.
I see some problems in your code:
When you are creating the UITableViewCell instance, you create an UIImageView image2 that is not assigned and therefore leaks memory. Is not normal ?
You do not need to get a reference to the UIImageView of the cell by tag. An UITableViewCell already has an UIImageView and its image can be set with the cell.imageView.image property.
Where are you loading the UIImage ? You say you are storing the image path, but there is no code for loading image from this path.