Loading an image into UITableViewCell from an NSArray - iphone

I have several hunderd .jpgs in /Resources within an iOS project.
Here is the viewDidLoad method:
- (void)viewDidLoad {
NSArray *allPosters = [[NSBundle mainBundle] pathsForResourcesOfType:#"jpg" inDirectory:#"."];
[super viewDidLoad];
}
The above successfully loads all of the .jpgs into an NSArray.
I simply need to display all of the .jpgs within this array in UITableViewCells in a UITableView
Here is the -(UITableViewCell *)tableView:cellForRowAtIndexPath: method:
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
NSDictionary *posterDict = [allPosters objectAtIndex:indexPath.row];
NSString *pathToPoster= [posterDict objectForKey:#"image"];
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell ==nil ) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]autorelease];
}
UIImage *theImage = [UIImage imageNamed:pathToPoster];
cell.ImageView.image = [allPosters objectAtIndex:indexPath.row];
return cell;
}
I know the issue is with cell.ImageView.image, but am not sure what the issue is? How can I grab each .jpg from the array and display in each row?

NSArray *allPosters = [[NSBundle mainBundle] pathsForResourcesOfType:#"jpg" inDirectory:#"."];
This will give you an array of paths (as suggested by the method name). Those paths are NSStrings.
But you are assigning this array to a local variable, and this variable will be gone after you left viewDidLoad.
so you have to change it into something like this:
allPosters = [[[NSBundle mainBundle] pathsForResourcesOfType:#"jpg" inDirectory:#"."] retain];
Another one:
NSDictionary *posterDict = [allPosters objectAtIndex:indexPath.row];
NSString *pathToPoster= [posterDict objectForKey:#"image"];
And this would definitely crash if you would have assigned the array correctly.
Change it into
NSString *pathToPoster = [allPosters objectAtIndex:indexPath.row];
Next one:
UIImage *theImage = [UIImage imageNamed:pathToPoster];
cell.ImageView.image = [allPosters objectAtIndex:indexPath.row];
UIImages imageNamed: doesn't work with paths, it needs filenames. And of course you want to assign the real image to the imageview and not the path to the poster. So change it:
UIImage *theImage = [UIImage imageNamed:[pathToPoster lastPathComponent]];
cell.imageView.image = theImage;

Try using [UIImage imageWithContentsOfFile:pathToPoster] rather than imageNamed. And set the value to the UIImage object.

It's probably just a typo, but it should be:
//lowercase "i" in imageView
cell.imageView.image = [allPosters objectAtIndex:indexPath.row];
Also- you are creating UIImage *theImage, but then you don't use it. What's going on there?

Related

JSON Image Parsing/Prefixed URL

I have established successful parsing of text and images in a table view using JSON/PHP/MYSQL. I am only storing the location of the images in the database and the actual images are stored in a directory on my server. The only thing that is stored related to the image in the database is the name. Example car.jpg. What I want to do is prefix the URL of the image location on my server so they can be parsed without me having to go into the DB and manually entering the URL. Here is some of my code...
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"studentsCell";
StudentsCell *cell = (StudentsCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"StudentsCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSDictionary *studentsDict = [students objectAtIndex:indexPath.row];
//I want to prefix the URL for the key imagepath but i dont know where and how to do it.
NSURL *imageURL = [NSURL URLWithString:[studentsDict objectForKey:#"imagepath"]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *imageLoad = [[UIImage alloc] initWithData:imageData];
cell.imageView.image = imageLoad;
NSString *name = [NSString stringWithFormat:#"%# %#", [studentsDict valueForKey:#"first"], [studentsDict valueForKey:#"last"]];
cell.title.text = name;
NSString *subtitle = [NSString stringWithFormat:#"%#", [studentsDict objectForKey:#"email"]];
cell.subtitle.text = subtitle;
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(265, 6, 44, 44);
[button setImage:[UIImage imageNamed:#"email.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(email:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
// cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellbackground.png"]];
return cell;
}
Let's assume you had something like:
NSURL *baseURL = [NSURL URLWithString:#"http://www.your.site.here/images"]; // whatever the folder with the images is
Then you could do:
NSURL *imageURL = [baseURL URLByAppendingPathComponent:[studentsDict objectForKey:#"imagepath"]];
By the way, you should consider using a UIImageView category, such as SDWebImage. Then, instead of loading a NSData with the image data synchronously, you can do an asynchronous image load:
[cell.imageView setImageWithURL:imageURL
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
The placeholder is what should be shown while the image is being loaded (perhaps just a blank image), and SDWebImage will then asynchronously retrieve the image and update the cell when it's retrieved. This will yield a far more responsive user interface. It will also avail yourself of image caching (so if you scroll down and then back up, the image won't be retrieved again).
AFNetworking has a similar UIImageView category, but not quite as robust of an implementation. But if you're already using AFNetworking, it's an option.

Fetching and displaying facebook profile picture in a UIImage

I'm trying to make a facebook friend picker displaying the friends who currently have the app installed that are also facebook friends with the current user.
Here I'm fetching the user's facebook profile picture but, I seem to have a warning where the last statement is not used. Thanks for your help.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"friendCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PFUser *facebookID = [[PFUser alloc] init];
facebookID = [friendUsers objectAtIndex:0];
NSString *fbIdString = [[NSString alloc] init];
fbIdString = [facebookID objectForKey:#"fbId"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
NSURL *profilePictureURL = [NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=large", fbIdString]];
NSData *picData = [NSData dataWithContentsOfURL:profilePictureURL];
UIImage *fbPic = (UIImage *)[self.view viewWithTag:1001];
[fbPic initWithData:picData];
}
// Configure the cell...
return cell;
}
You need to actually assign the result of the initWithData: call to your fbPic image.
E.g.
fbPic = [fbPic initWithData: picData];
From the apple documentation on UIImage:
- (id)initWithData:(NSData *)data
Parameters
data -
The data object containing the image data.
Return Value
An initialized UIImage object, or nil if the method could not initialize the image from the specified data.
A couple of things:
UIImage *fbPic = (UIImage *)[self.view viewWithTag:1001]; - I think you're trying to get the UIImageView from the cell?
There's no UIImageView where you're actually showing the image.
It should be something like this:
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
NSURL *profilePictureURL = [NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=large", fbIdString]];
NSData *picData = [NSData dataWithContentsOfURL:profilePictureURL];
UIImageView *fbPicImageView = (UIImageView *)[self.view viewWithTag:1001];
[fbPicImageView setImage:[UIImage imageWithData:picData]];
}

how to show image in table cell through json parsing

NSURL *url = [NSURL URLWithString:#"yourimage"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[[UIImage alloc] initWithData:data] autorelease];
This code i used to get the image but how to show it in table cell.
try this,
- (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] autorelease];
}
NSURL *url = [NSURL URLWithString:[imageArray objectAtIndex: [indexPath row]]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[[UIImage alloc] initWithData:data] autorelease];
[[cell imageView] setImage:img];
return cell;
}
FirstLy You need To parse That JSON file In Your iOS Application.
I guess You get Some URL from That JSON for The Image So You need To Download Image Form That Prased URL and Can set That IMage Over ANy UIIMageView and you can set That UIIMageView to The Content View Of UITablViewCell.
Here You Need To Just Manage One THing Suppose You have Many Images To be Downlaod Form The Particular path.So You should Take Care of The UI Interaction also
Here Is Good Example Of How TO download Images form The URL and set That DownLoaded Image Over The UIImageView and set That UIImageView on to the ContentView of UITableViewcell.In this Example you'll also see The Way of How Can you Add The These Images Over The TableViewcEll.
Here Is The Link For That Example
I hope It may help You.
You can do it with
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
[[cell imageView] setImage:img];
But thats probably not going to run very well because you're downloading the images synchronously and that will most likely make your app stutter.
You should use lazy loading for the images, for an example take a look at
http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html
This works for me:
NSURL *url = [NSURL URLWithString:[aTweet objectForKey:#"profile_image_url"]];
NSData *imgData = [NSData dataWithContentsOfURL:url];
cell.imageView.image = [UIImage imageWithData:imgData];

don't want to use dequeueReusableCellWithIdentifier for UITableViewCell

In my UITableViewCells I need to download different image for each cell, what should I do for such kind of problem...
You should use that method still, and then configure each cell independently. Just make sure your cell setup isn't on your construction block
UITableViewCell *cell = [tableView dequeue..];
if (!cell) {
cell = ...;
}
cell.image = ...;
item will be your dictionary of images
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier"]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
NSDictionary *item = (NSDictionary *)[self.content objectAtIndex:indexPath.row];
cell.textLabel.text = [item objectForKey:#"mainTitleKey"];
cell.detailTextLabel.text = [item objectForKey:#"secondaryTitleKey"];
NSString *path = [[NSBundle mainBundle] pathForResource:[item objectForKey:#"imageKey"] ofType:#"png"];
UIImage *theImage = [UIImage imageWithContentsOfFile:path];
cell.imageView.image = theImage;
return cell;
}

Cancel Selector in UITableViewCell

I have scenario that in which i am using selector in TableViewCell as bellow and when I click on back button in my view I want to cancel that selector and I am sending dictionary as object in Selector
My code is as bellow
In Header File
NSMutableDictionary* photoDict;
NSMutableDictionary* dictImages;
In .M file
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell==nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
[[NSBundle mainBundle]loadNibNamed:#"MyCellNib" owner:self options:Nil];
cell = detailChainObj;
}
NSString* avatarURL =#"image_Url"; //Any url of image for cell.
NSString *key =[[NSString alloc] initWithFormat:#"Key%d%d",indexPath.section,indexPath.row];
dictImages = [NSDictionary dictionaryWithObjectsAndKeys:imageViewCell,#"Img",imgURL,#"imgURL",key,#"key", nil];
[self performSelectorInBackground:#selector(DownloadLinkzImageOfUser:) withObject:dictImages];
if([photoDic valueForKey:keyAvt])
{
NSData* data = (NSData*)[photoDic valueForKey:key];
imageViewCell.image = [UIImage imageWithData:data];
}
else
{
[self performSelectorInBackground:#selector(DownloadImagesForCell:) withObject:dictImages];
}
}
//
-(void)DownloadImagesForCell:(NSDictionary *)result
{
UIImageView* img = (UIImageView*)[result objectForKey:#"Img"];
NSString* urlAvt = [result valueForKey:#"imgURL"];
if([urlAvt isEqualToString:#"No Image"])
{
img.image = [UIImage imageNamed:#"noimg.png"];
}
else
{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imgURL]];
img.image = [UIImage imageWithData:data];
[photoDic setValue:data forKey:[NSString stringWithFormat:#"%#",[result valueForKey:#"key"]]];
}
}
Now I want to cancel this selecter when I press back button
and please keep in mind that I have already use
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(DownloadImagesForCell:) object:dictImages];
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsobject_Class/Reference/Reference.html
I guess this method works for performSelector:withObject:afterDelay: only.