Why Image is not Shown in cellforRowAtIndexPath in objective C - ios

I am new in iOS and I am facing problem regarding to show image in the Image View from Web Service.I am using code like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *STI=#"STI";
NewsTableViewCell *cell = (NewsTableViewCell *)[tableView dequeueReusableHeaderFooterViewWithIdentifier:STI];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"NewsTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.accessoryType=UITableViewCellAccessoryNone;
}
NSString *strImgURLAsString = [NewsImageArray objectAtIndex:indexPath.row];
[strImgURLAsString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *imgURL = [NSURL URLWithString:strImgURLAsString];
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:imgURL] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) {
img = [[UIImage alloc] initWithData:data];
if (img==nil) {
// img=[UIImage imageNamed:#"userimage.png"];
}
cell.newsimage.image=img;
// pass the img to your imageview
}else{
NSLog(#"%#",connectionError);
}
}];
cell.Headlbl.text=[NSString stringWithFormat:#"%#",[headarray objectAtIndex:indexPath.row]];
NSString *aux = [shortnamearray objectAtIndex:indexPath.row];
NSString * htmlString = #"<html><body>";
NSString *htmlString2=#"</body></html>";
NSString * NewString=[NSString stringWithFormat:#"%#%#%#",htmlString,aux,htmlString2];
NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[NewString dataUsingEncoding:NSUnicodeStringEncoding] options:#{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
cell.bodylbl.attributedText=attrStr;
cell.bodylbl.textAlignment=NSTextAlignmentCenter;
cell.bodylbl.textColor=[UIColor whiteColor];
[cell.bodylbl setFont:[UIFont fontWithName:#"Arial" size:16]];
cell.backgroundColor = cell.contentView.backgroundColor;
// cell.bodylbl.text=[NSString stringWithFormat:#"%#",[shortnamearray objectAtIndex:indexPath.row]];
// cell.randrid.text=[NSString stringWithFormat:#"%#",[idarray objectAtIndex:indexPath.row]];
return cell;
}
Image Path - http://qaec.teams.in.net/UploadedFiles/Tommy Schaefer, of his role in the slaying, for which he is serving 18 year.png
http://qaec.teams.in.net/UploadedFiles/Tommy%20Schaefer,%20of%20his%20role%20in%20the%20slaying,%20for%20which%20he%20is%20serving%2018%20year.png
When Image Does not contain any gap it shows image
But when the Image contain any gap it not show image.How to solve this problem.Thanks in Advance!

You can use following method in UITableviewCell class. In your case add code in NewsTableViewCell.m When cell is created that time drowRect method is called. So in this method you need to set setClipsToBounds property of image view for which you setting the image to YES. This will solve your issue.
-(void)drawRect:(CGRect)rect
{
[super drawRect:rect];
self.profilePicImgView.layer.cornerRadius=self.profilePicImgView.frame.size.width/2;
[self.profilePicImgView setClipsToBounds:YES];
[self.profilePicImgView layoutIfNeeded];
[self.profilePicImgView setNeedsDisplay];
}

There is no need to use any other library etc. Your code is mistake on this line:
[strImgURLAsString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
Have a look at this what does it do? Nothing. You should reassign the variable strImgURLAsString to this then it should work:
strImgURLAsString = [strImgURLAsString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

For better performance, you can try this library called SDWebImage.
[imageView sd_setImageWithURL:[NSURL URLWithString:#"http://qaec.teams.in.net/UploadedFiles/Tommy%20Schaefer,%20of%20his%20role%20in%20the%20slaying,%20for%20which%20he%20is%20serving%2018%20year.png"] placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
Also
You need to make sure that you have written this in your plist file

Use like this:
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:imgURL] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) {
dispatch_async(dispatch_get_main_queue(), ^{
img = [[UIImage alloc] initWithData:data];
if (img==nil) {
// img=[UIImage imageNamed:#"userimage.png"];
}
cell.newsimage.image=img;
// pass the img to your imageview
});
}else{
NSLog(#"%#",connectionError);
}
}];

I know it's good to idea to load image url in Imageview like the way you have written for better understanding of process. But maintaining cache is also important thing to consider. For better performance, I recommend you to use a very good library called SDWebImage. It helps you out in loading images faster with it's cache mechanism. Try this out. With this library it's this much simple.
[imageView sd_setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
Here is another one.
If you are using AFNetworking in your app, use below code to do that.
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
requestOperation.responseSerializer = [AFImageResponseSerializer serializer];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response: %#", responseObject);
_imageView.image = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Image error: %#", error);
}];
[requestOperation start];

Related

Data dosen't load on some Tableview cell from JSON parse

I making here simple application on XCODE 7.1. I just display 2 label and 1 image in tableview cell.I am parsing data from this URL. I am simply load data in TableviewHere i put the code of ViewController.m file
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.alpha = 1.0;
[self.view addSubview:activityIndicator];
activityIndicator.center = CGPointMake([[UIScreen mainScreen]bounds].size.width/2, [[UIScreen mainScreen]bounds].size.height/2);
[activityIndicator startAnimating];//to start animating
// Do any additional setup after loading the view, typically from a nib.
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:#"http://www.androidbegin.com/tutorial/jsonparsetutorial.txt"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(#"Error: %#", error);
} else {
[activityIndicator stopAnimating];
_responsedic = (NSDictionary*) responseObject;
_Worldpopulation = [_responsedic valueForKey:#"worldpopulation"];
_imageURL = [_Worldpopulation valueForKey:#"flag"];
_country = [_Worldpopulation valueForKey:#"country"];
_population = [_Worldpopulation valueForKey:#"population"];
NSLog(#"Data:%#",_imageURL);
NSLog(#"Population",_population);
NSLog(#"Country",_country);
// NSLog(#"%#",_MovieList);
//NSLog(#"Array: %#",_imageURL);
//NSLog(#"%#",responseObject);
}
}];
[dataTask resume];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 10;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *Identifier = #"mycell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:Identifier];
// Set and load the images
[cell.imageView sd_setImageWithURL:[_imageURL objectAtIndex:indexPath.row] placeholderImage:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
// Get rid of the activity indicator when the image has been loaded
}];
cell.textLabel.text = [_country objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [_population objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//NSString *rowValue = self.friends[indexPath.row+1];
NSString *message = [[NSString alloc] initWithFormat:#"You selected %#",[_country objectAtIndex:indexPath.row]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"YOU SELECT"
message:message
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
I am using AFNetworking 3.0 and SDWebImage for image loading.Data parse successfully and and displayed in tableview.I attached screenshot below
Problem is what the all data are not displayed in the tableview cell i also put the Alert dialog on each cell of tableview data successfully loaded but not displayed in cell. I search everywhere i can't find solution for this i am using 3G connection so net speed is not an issue Please someone help.
Try to reload table view with updated data in completion block.
NSURL *URL = [NSURL URLWithString:#"http://www.androidbegin.com/tutorial/jsonparsetutorial.txt"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(#"Error: %#", error);
} else {
[activityIndicator stopAnimating];
_responsedic = (NSDictionary*) responseObject;
_Worldpopulation = [_responsedic valueForKey:#"worldpopulation"];
_imageURL = [_Worldpopulation valueForKey:#"flag"];
_country = [_Worldpopulation valueForKey:#"country"];
_population = [_Worldpopulation valueForKey:#"population"];
NSLog(#"Data:%#",_imageURL);
NSLog(#"Population",_population);
NSLog(#"Country",_country);
// NSLog(#"%#",_MovieList);
//NSLog(#"Array: %#",_imageURL);
//NSLog(#"%#",responseObject);
//Added Code -> Reloading data on Main queue for update
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableview reloadData];
});
}
}];
[dataTask resume];
Hope, it'll help you.
Thanks.
1) Parse Data and after getting data relaod table
-(void)ParseData
{
NSURLSession * session = [NSURLSession sharedSession];
NSURL * url = [NSURL URLWithString: #"http://www.androidbegin.com/tutorial/jsonparsetutorial.txt"];
//Create URLReques
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
// Set Method POST/GET
[request setHTTPMethod:#"GET"];
// Asynchronously Api is hit here
NSURLSessionDataTask* dataTask=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) //If error nil
{
//Serialization data
NSDictionary * json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"json %#",json);
array=[json valueForKey:#"worldpopulation"];
dispatch_async(dispatch_get_main_queue(), ^(void) {
if(array.count!=0)
{
//Reload table View
[_tblView reloadData];
}
});
}
else
{
//failure;
}
}];
[dataTask resume] ; // Executed task
}
2) Table View DataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(array.count!=0)
{
return [array count];
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell;
//= [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.backgroundColor =[UIColor whiteColor];
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UILabel *lblCountry=(UILabel*)[cell viewWithTag:2];
lblCountry.text= [[array objectAtIndex:indexPath.row]valueForKey:#"country"];
UILabel *lblPopulation=(UILabel*)[cell viewWithTag:3];
lblPopulation.text= [[array objectAtIndex:indexPath.row]valueForKey:#"population"];
UIImageView *img = (UIImageView *)[cell viewWithTag:1];
[img setImageWithURL:[NSURL URLWithString:[[array objectAtIndex:indexPath.row]valueForKey:#"flag"]]];
return cell;
}

Does AFNetworking cache images load automatically or do we have to do it manually?

I'm using AFNetworking to load images from JSON feed.
In here, first time when user opens the app, images load from the internet. It's fine.
But when user go back and come again from another view, while using the app, images should load from the cache, not from the internet.
How can I do that?
- (void)loadDetailData
{
detailPost = nil;
NSString *detailUrl = [NSString stringWithFormat:#"%#", self.Details.firsturl];
AFHTTPRequestOperationManager *detailManager = [AFHTTPRequestOperationManager manager];
[detailManager GET:detailUrl parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
detailPosts = (NSDictionary *)responseObject;
detailPost = [NSMutableArray array];
NSArray *result = [detailPosts objectForKey:#"posts"];
for (NSDictionary *all in result)
{
Categories *newCategory = [Categories new];
NSDictionary *thumbnail_images = [all objectForKey:#"thumbnail_images"];
NSDictionary *mediumImages = [thumbnail_images objectForKey:#"medium"];
newCategory.detailimageUrl = [mediumImages objectForKey:#"url"];
newCategory.title = [all objectForKey:#"title"];
newCategory.mogowebUrl = [all objectForKey:#"url"];
// NSLog(#"%#", newCategory.title);
[detailPost addObject:newCategory];
[self.maintableView reloadData];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [detailPost count];;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FirstTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"reuseIdentifier"];
Categories *details = [detailPost objectAtIndex:indexPath.row];
cell.detailTitle.text = details.title;
NSString *imageurl = [NSString stringWithFormat:#"%#", details.detailimageUrl];
NSURL *imgurl = [NSURL URLWithString:imageurl];
[cell.detailImageView setImageWithURL:imgurl placeholderImage:nil];
// [cell addSubview:cell.subView];
cell.layer.masksToBounds = NO;
cell.layer.cornerRadius = 5;
cell.layer.borderColor = [UIColor blackColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0, 1);
cell.layer.shadowRadius = 2.0;
cell.layer.shadowColor = [UIColor lightGrayColor].CGColor;
return cell;
}
tl;dr
Use -setImageWithURLRequest:placeholderImage:success:failure:
NSURLRequest *imageRequest =
[NSURLRequest requestWithURL:[NSURL URLWithString:imgurl]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:60];
[cell.detailImageView setImageWithURLRequest:imageRequest
placeholderImage:nil
success:nil
failure:nil];
Image Cache + AFNetworking
Import the UIImageView+AFNetworking header and viola! UIImageView class now has several methods to download images and also, to cache them!
In-memory Caching: You can use following methods for simple in-memory caching.
– setImageWithURL:
– setImageWithURL:placeholderImage:
Image will be retrieved from the in-memory cache, if the image exists, otherwise it will be downloaded from the URL and stored in the in-memory cache.
Example:
[imageView setImageWithURL:[NSURL URLWithString:imageURL]];
//here, placeholder image is set immediately.
[imageView setImageWithURL:[NSURL URLWithString:imageURL]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
Disk Caching: You can use following method if you need to cache the image for longer than the user’s session. (tip: check NSURLRequestCachePolicy in NSURLRequest class)
-setImageWithURLRequest:placeholderImage:success:failure:
Note: If a success block is specified, it is the responsibility of the block to set the image of the image view before returning. If no success block is specified, the default behavior of setting the image with self.image = image is applied.
Example:
NSURLRequest *imageRequest =
[NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:60];
[imageView setImageWithURLRequest:imageRequest
placeholderImage:[UIImage imageNamed:#"placeholder.png"]
success:nil
failure:nil];

UIImageView category does not update unless you interact with UITableViewController

To see a demonstration of the problem along with code, please have a look at the following 60 second video.
Here is a simple project demonstrating the problem.
Challenge, see if you can make the image appear without having to touch the tableviewcontroller during runtime using the category I've created.
I have created a simple UIImageView category where I expose an imageURL property which when set should then start an asynchronous download. When the completion block is called, I set the class' image property to the image downloaded.
I then have a class that inherits from UITableViewController where I import my custom UIImageView category. I start the download in the willDisplayCell: method by setting the cell's imageview imageURL property. The image is asynchronously downloaded and is set, but the cell's imageview does not update unless I scroll the cell away from the table, or I click on the cell itself.
I have tried things like [self setNeedsDisplay]; and a few other things like executing the setting of the image on the main thread but all to no avail.
Can someone take a look and let me know what I should be doing?
Some code:
UIImageView+AsyncDLImageView.h
#import <UIKit/UIKit.h>
#interface UIImageView (AsyncDLImageView)
#property (nonatomic, retain) NSURL *imageURL;
#end
UIImageView+AsyncDLImageView.m
#import "UIImageView+AsyncDLImageView.h"
#implementation UIImageView (AsyncDLImageView)
- (void)setImageURL:(NSURL *)imageURL{
[self loadImageWithURL:imageURL completionHandler:^(UIImage *image, NSError *error) {
if(!error) {
NSLog(#"image has been set: %#", image);
self.image = image;
}
}];
}
-(NSURL *)imageURL{
return self.imageURL;
}
-(void)loadImageWithURL:(NSURL*)url completionHandler:(void(^)(UIImage *image, NSError *error))completionBlock{
NSLog(#"set image url request called: %#", [url absoluteString]);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
NSLog(#"no error");
UIImage *image = [[UIImage alloc] initWithData:data];
completionBlock(image, nil);
} else{
completionBlock(nil, error);
NSLog(#"error");
}
}];
}
It would appear that because the imageView on the table cell is not initialised that the image won't display. I added a transparent placeHolder image (make the size you want the image to be) and use that while you are waiting for the image to load. (this worked for me)
so I changed the code as follows...
DisplayXMLImageDataTVC.m
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_xmlImageURLArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"xmlCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.imageView.image = [UIImage imageNamed:#"placeHolder"];
}
[cell.imageView setImageURL:[_xmlImageURLArray objectAtIndex:indexPath.row]];
return cell;
}
and your category class back to what it was....
- (void)setImageURL:(NSURL *)imageURL
{
// objc_setAssociatedObject(self, #selector(imageURL), imageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self loadImageWithURL:imageURL completionHandler:^(UIImage *image, NSError *error) {
if(!error) {
self.image = image;
}
}];
}
-(void)loadImageWithURL:(NSURL*)url completionHandler:(void(^)(UIImage *image, NSError *error))completionBlock{
NSLog(#"set image url request called: %#", [url absoluteString]);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
NSLog(#"no error");
UIImage *image2 = [[UIImage alloc] initWithData:data];
completionBlock(image2, nil);
} else{
completionBlock(nil, error);
NSLog(#"error");
}
}];
}
The issue seems to be that UITableViewCell uses the initial frame of the imageView to layout the cell. If it is not set, then you get a 0x0 frame, and even when you set the image later, the frame doesn't change. If you set it to some placeholder image, then it continues to use the frame from that placeholder image, which might not be what you want.
A possible solution would be to have a custom UITableViewCell, which overrides layoutSubviews and sets the frame according to the image that you have. And from your imageView category, after you set the image, call [self setNeedsLayout]. This will cause layoutSubviews to be called on the next redraw.
You could look at this also - http://www.wrichards.com/blog/2011/11/sdwebimage-fixed-width-cell-images/
The reason for that is cell is not redrawn after the image is set. Usually we send an asynchronous request for an image in cellForRowAtIndexPath and after we get the image, we call cell setNeedsLayout.
So you can do the following.
- (void)setImageURL:(NSURL *)imageURL
{
UITableViewCell *cell = (UITableViewCell *)self.superview.superview;
[self loadImageWithURL:imageURL completionHandler:^(UIImage *image, NSError *error) {
if(!error) {
NSLog(#"image has been set: %#", image);
self.image = image;
[cell setNeedsLayout];
}
}];
}

Getting url from Database and putting as an image for UITableView

All,
I need to assign a picture to a UITableView. Each row has a different picture. The data for each row comes from a database and a row on that database has an ID, the ID in another database is linked and that has a URL in that table for the image.
So within cellforRowAtIndexPath we have :
NSDictionary *postValues = #{#"myParam": apt[#"barID"]};
// Do any additional setup after loading the view, typically from a nib.
self.client = [MSClient clientWithApplicationURLString:#"https://outnight-mobile.azure-mobile.net/" applicationKey:#"okYeRGfBagYrsbkaqWIRObeDtktjkF10"];
[self.client invokeAPI:#"photos"
body:postValues
HTTPMethod:#"POST"
parameters:nil
headers:nil
completion:^(id result, NSHTTPURLResponse *response, NSError *error) {
if (error) {
NSLog(#"Error %#", error );
} else
{
NSString *string = [NSString stringWithFormat:#"%#", [result objectForKey:#"rows"]];
NSString *stringWithoutbracketsend = [string stringByReplacingOccurrencesOfString:#")" withString:#""];
NSString *stringWithoutbracketsfront = [stringWithoutbracketsend stringByReplacingOccurrencesOfString:#"(" withString:#""];
NSString *completion = [stringWithoutbracketsfront stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *newStr = [completion substringFromIndex:1];
NSString *finalstring = [newStr substringToIndex:newStr.length-(newStr.length>0)];
NSLog(#"%#", finalstring);
[cell.imageView setImageWithURL:[NSURL URLWithString:finalstring] placeholderImage:[UIImage imageNamed:#"greybox40.png"]];
}
}];
That brings in the url from the table, which was JSON and I removed all the tags to get a string thats just http://blag.com/bah.jpg' This is the easy bit.
I am using SBWebImage for putting the image in the uitableview async which is fine too. What is the best way of putting the images on each row from the url. is it best with a SWITCH statement ? Is it best with an array of URL's and then displaying them. Is it best to move the database connectivity from cellforIndexRowPath? Can anyone advice please ?
first of all create a custom view cell for the uitableview. And then add subviews like images, labels to the custom cell.Get the data from the database to an array of images, arrays of ID'sIn the tableview delegate methods at cellforrowatindex use the code.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{ static NSString *CellIdentifier = #"Cell";
if(tableView == myTableView){
FirstViewCustomCell *cell = (FirstViewCustomCell *)[myTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"FirstViewCustomCell" owner:self
options:nil];
cell = customCell;
customCell = nil;
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
//Get the data from the database.
cell.customimage.image = [imagesarr objectatIndex:indexpath.row];
cell.textlabel.text = [arrayofID objectatIndex:indexpath.row];
}
Parse the data seperately..in an method and then
Store images in an array..As you want top three images..
If you are saving the urls of image in an object and then array..Use below code
for(int i=0;i<3;i++)
{
ImagesObject *Obj=[imagesArray objectAtIndex:i];
[cell.userProfilePicImage setImageWithURL:[NSURL URLWithString:Obj.imageURLString]
placeholderImage:[UIImage imageNamed:#"greybox40.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
{
if (!error && image)
{
}
}];
}
(or) if you are not saving in an object then use below code.
for(int i=0;i<3;i++)
{
NSString *imageURLString=[imagesArray objectAtIndex:i];
[cell.userProfilePicImage setImageWithURL:[NSURL URLWithString:imageURLString]
placeholderImage:[UIImage imageNamed:#"greybox40.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
{
if (!error && image)
{
}
}];
}
Hope it helps you...

how can i display images in uitableviewcells using Asyncronous concept in ios

I have to show some post blogs into a UITableView. When I have retreived all web service data.
This is my sample code.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible=YES;
NSError *err;
NSString *strResponse=[[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"response is %#",strResponse);
dit=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:&err];
NSArray *arrResults = [dit valueForKey:#"classifieds_mst"];
listOfObjects = [NSMutableArray array];
for(dictRes in arrResults)
{
Attributes *at = [[Attributes alloc]init];
at.classimage=[dictRes valueForKey:#"image_name"];
[listOfObjects addObject:at];
}
[tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier=#"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"identifier"];
}
classifiedimage=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 300, 80)];
[cell.contentView addSubview:classifiedimage];
Attributes *att = [listOfObjects objectAtIndex:indexPath.row];
NSString *str;
str=att.classimage;
classifiedimage.image = [UIImage imageNamed:str];
return cell;
}
My requirement is i want to display images in uitableviewcells using json parser.I wrote the above code.But the images are not displayed in uitableviewcells.I want to use to display images in uitableviewcells using Asyncronous concept.Please give me any idea.I am new to the programming.Thanks in advance.
This is my json data.
{"classifieds_mst":[{"classified_id":83,image_name":"1389006378_butterfly.jpeg"},
{"classified_id":82,"image_name":"ttt.jpj"},{"classified_id":83,”image_name":"ttttt.jpj”}
imageNamed is used to load image from local bundle (in app).
imageWithData:dataWithURL is used to load images from url's.
You have to append domain name in your image name: (image_name":"1389006378_butterfly.jpeg), so that you can get URL of the image which is stored on server, now you can use below code:
[cell.yourImageView setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:yourImageNameHere]]]];
By referring to your JSON data, it just contain the image_name only. So first of all, you need to build the actual image url. (copy paste that actual url in browser to make sure image is available in server).
Once you have the image url, then you can use AsyncImageView instead of UIImageView in your cell. It will handle the asynchronous thing for you as you just need to set the image url only. Thats the way to go.
One more suggestion is to recheck you cellForRowAtIndexPath, as the code always creating imageView's and adding to cell each time the cell is created. That's not required when you are reusing a cell. You just need to create the image view once when cell is allocated and just assign a tag to imageview and then get the imageview based on this tag and then use it. Just for your reference, I'm posting a sample code:
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"identifier"];
AsyncImageView *imgView= [[[AsyncImageView alloc]init]autorelease];
imgView.tag = 1000;
imgView.contentMode = UIViewContentModeScaleAspectFill;
[cell.contentView addSubview:imgView];
}
AsyncImageView *imgView= (AsyncImageView*)[cell.contentView viewWithTag:1000];
contactImgView.frame = CGRectMake(0, 0, 300, 80);
//imgUrl is the actual url of image that is available in datasource
[contactImgView setImageURL:imgUrl];
Hope it is clear.
if you are using the AFNetworking then use it to download your image like
NSArray *keys = #[#"UserID", ];
NSArray *objects = #[#(userId)];
NSDictionary *parameter = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:
[NSURL URLWithString:BaseURLString]];
[httpClient setParameterEncoding:AFJSONParameterEncoding];
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST"
path:#"UserService.svc/GetUserInfo"
parameters:parameter];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSError* error = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
});
}];
[operation start];
and for image use this
[cell.userImage setImageWithURLRequest:[[NSURLRequest alloc] initWithURL:[NSURL URLWithString:userBasicInfo.imageUrl]]
placeholderImage:[UIImage imageNamed:#"facebook-no-user.png"]
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
weakCell.userImage.image = image;
[weakCell setNeedsLayout];
} completion:^(BOOL success, NSError *error) {
NSLog(#"%#",[error localizedDescription]);
}];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
}];
You Create a subclass of UITableViewCell (can call it blogTableViewCell) for your cell and use that in the table.
Initialize blogTableViewCell with the JSON data (you could have an NSDictionary store the JSON info)
In blogTableViewCell create a function that loads image data on another thread (so the main thread can continue its course) and once the image is loaded, update the uiimageview on the cell to display it (This should be done on the main thread as it is a UI update)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
//cell.textLabel.text = [[resultArray objectAtIndex:indexPath.row] valueForKey:#"name"];
cell.detailTextLabel.text = [[resultArray objectAtIndex:indexPath.row] valueForKey:#"designation"];
cell.imageView.image=[UIImage imageNamed:[[resultArray objectAtIndex:indexPath.row] valueForKey:#"image"]] ;
//[cell.imageView setImageWithURL:[NSURL URLWithString:[[resultArray objectAtIndex:indexPath.row] objectForKey:#"image"]]];
// NSURL *url = [NSURL URLWithString:[resultArray objectAtIndex:indexPath .row]];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[resultArray objectAtIndex:indexPath.row] valueForKey:#"image"] ]];
cell.imageView.image = [UIImage imageWithData:imageData];
return cell;
}

Resources