how to show images from web services in grid view - iphone

I am getting the images from the web services in list view but i want to show them in grid
view. As i am displaying the images in list view,In grid view how i can do this ? please help.this is how my code looks:-
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *CELLIDENTIFIER=#"CELL";
UITableViewCell *cell=nil;
if (cell==nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CELLIDENTIFIER] autorelease];
CGRect imageFrame = CGRectMake(2, 8, 80, 60);
NSURL *url = [NSURL URLWithString:[arrayListG objectAtIndex: [indexPath row]]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[[UIImage alloc] initWithData:data] autorelease];
UIImageView *customImage = [[[UIImageView alloc] initWithFrame:imageFrame] autorelease];
customImage.image=img;
[cell.contentView addSubview:customImage];
}
return cell;
}

Better to use this awesome library for gridview
How to implement and integrate in project everything is documented on this link.check this out AQGridview

Gridview = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0, 320, 480)];//your frame
Gridview.backgroundColor=[UIColor clearColor];
int row=0;
int column=0;
int rows=4;
int cols=5;
for (int i=0; i<rows*cols; i++)
{
if((row%4==0)&&(row>0))
{
row=0;
column++;
}
else{
row++;
}
CGRect imageFrame = CGRectMake(row*80+10, column*60+10, 80, 60);//your imageview frame
NSURL *url = [NSURL URLWithString:[arrayListG objectAtIndex:i]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[[UIImage alloc] initWithData:data] autorelease];
UIImageView *customImage = [[[UIImageView alloc] initWithFrame:imageFrame] autorelease];
customImage.image=img;
[Gridview addSubView:customImage];
}
[Gridview setContentSize:CGSizeMake(rows*90, cols*70)];
Gridview is your scrollview add it in IB or programatically as you desire in my case i have added it programatically. set content size and frame as per your requirement

Please modify your code as below.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *CELLIDENTIFIER=#"CELL";
UITableViewCell *cell=nil;
if (cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CELLIDENTIFIER];
CGRect imageFrame = CGRectMake(2, 8, 80, 60);
UIImageView *customImage = [[UIImageView alloc] initWithFrame:imageFrame];
customImage.tag = 1;
[cell.contentView addSubview:customImage];
}
UIImageView *customImage = (UIImageView *)[cell viewWithTag:1];
NSURL *url = [NSURL URLWithString:[arrayListG objectAtIndex: [indexPath row]]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
customImage.image =img;
return cell;
}

You can try UIcollectionView a new control for ios,it is similar to UItabel view and easy to integrate.
Please have a look on these links
http://ashfurrow.com/blog/uicollectionview-example
http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12

Related

TableView cell Labels are disappearing on scrolling, but visible for a selected cell?

As TableView cell labels are displayed on load but when the tableView is scrolled the tableview contents are not appearing. But if I select any of the cell then the labels in that particular cell are displaying.
Please help me. I have the same problem in different aspect too. I did not get any resolution for it.
Here is my code of cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
static NSString *CellIdentifier = #"newsTableCell";
UITableViewCell *cell = [self.newsTable dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
UILabel *user = [[UILabel alloc] initWithFrame:CGRectMake(84, 10,75,21)];
user.tag = 101;
[cell.contentView addSubview:user];
[user release];
UILabel *usr = (UILabel *)[cell viewWithTag:101];
usr.font = [UIFont boldSystemFontOfSize:12.0];
[usr setText:[appDelegate.usernames objectAtIndex:[indexPath row]]];
UILabel *status = [[UILabel alloc] initWithFrame:CGRectMake(154,10,69,21)];
status.tag = 102;
[cell.contentView addSubview:status];
[status release];
status = (UILabel *)[cell viewWithTag:102];
status.font = [UIFont boldSystemFontOfSize:12.0];
[status setText:[appDelegate.statistics objectAtIndex:[indexPath row]]];
UILabel *rival = [[UILabel alloc] initWithFrame:CGRectMake(220,10,80,21)];
rival.tag = 103;
[cell.contentView addSubview:rival];
[rival release];
UILabel *rivals = (UILabel *)[cell viewWithTag:103];
rivals.font = [UIFont boldSystemFontOfSize:12.0];
[rivals setText:[appDelegate.rivalusernames objectAtIndex:[indexPath row]]];
UILabel *gamename = [[UILabel alloc] initWithFrame:CGRectMake(84,27,208,21)];
gamename.tag = 104;
[cell.contentView addSubview:gamename];
[gamename release];
UILabel *gamenames = (UILabel *)[cell viewWithTag:104];
gamenames.font = [UIFont boldSystemFontOfSize:12.0];
[gamenames setText:[appDelegate.challengenames objectAtIndex:[indexPath row]]];
UILabel *time = [[UILabel alloc] initWithFrame: CGRectMake(84,47,149,21)];
time.tag = 105;
[cell.contentView addSubview:time];
[time release];
UILabel *times = (UILabel *)[cell viewWithTag:105];
times.font = [UIFont boldSystemFontOfSize:12.0];
[times setText:[appDelegate.remainingtime objectAtIndex:[indexPath row]]];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(12,10,67,58)];
imageView.tag = 106;
[cell.contentView addSubview:imageView];
[imageView release];
NSURL *url = [NSURL URLWithString:[appDelegate.imagepaths objectAtIndex:[indexPath row]]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
UIImageView *imgView = (UIImageView *)[cell viewWithTag:106];
imgView.image = img;
return cell;
}
first of all move these lines inside the if (cell==NIL):
if(cell == nil) {
cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *user = [[UILabel alloc] initWithFrame:CGRectMake(84, 10,75,21)];
user.tag = 101;
[cell.contentView addSubview:user];
[user release];
}
or you add a subview to the cell each time you reuse it, scrolling
and the same for:
UILabel *status = [[UILabel alloc] initWithFrame:CGRectMake(154,10,69,21)];
status.tag = 102;
[cell.contentView addSubview:status];
[status release];
and
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(12,10,67,58)];
imageView.tag = 106;
[cell.contentView addSubview:imageView];
[imageView release];
...etc etc
as a general rule: you add/alloc new objects just once when you first create a cell (inside the if (cell==nil))
then outside that if you just reuse all objects and change their properties, as text of image source...
Maybe the color of your UILabels is the same as the background color? When you select a cell and then you can see the text, it probably is because of the then highlighted cell color ...
And I also strongly suggest you make a cell subclass as cortez mentioned, this code is not read- nor maintainable ...
your implementation of the UITableView Cell is rong try this way
i Know your problem will solve.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
static NSString *CellIdentifier = #"newsTableCell";
UITableViewCell *cell = [self.newsTable dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *user = [[UILabel alloc] initWithFrame:CGRectMake(84, 10,75,21)];
user.tag = 101;
usr.font = [UIFont boldSystemFontOfSize:12.0];
[cell.contentView addSubview:user];
[user release];
UILabel *status = [[UILabel alloc] initWithFrame:CGRectMake(154,10,69,21)];
status.tag = 102;
status.font = [UIFont boldSystemFontOfSize:12.0];
[cell.contentView addSubview:status];
[status release];
UILabel *rival = [[UILabel alloc] initWithFrame:CGRectMake(220,10,80,21)];
rival.tag = 103;
[cell.contentView addSubview:rival];
[rival release];
}
else
{
UILabel *usr = (UILabel *)[cell viewWithTag:101];
status = (UILabel *)[cell viewWithTag:102];
rival = (UILabel *)[cell viewWithTag:103];
}
[usr setText:[appDelegate.usernames objectAtIndex:[indexPath row]]];
[status setText:[appDelegate.statistics objectAtIndex:[indexPath row]]];
[rival setText:[appDelegate.statistics objectAtIndex:[indexPath row]]];
return cell;
}
Initially I written the code as above. After the suggestion of meronix I have changed to below one. Please suggest.
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
if (tableView.tag ==16)
{
NSLog(#"%d",appDelegate.checkChallenges);
static NSString *CellIdentifier = #"newsTableCell";
UITableViewCell *cell = [self.newsTable dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *user = [[UILabel alloc] initWithFrame:CGRectMake(84, 10,75,21)];
user.tag = 101;
[cell.contentView addSubview:user];
[user release];
UILabel *status = [[UILabel alloc] initWithFrame:CGRectMake(154,10,69,21)];
status.tag = 102;
[cell.contentView addSubview:status];
[status release];
UILabel *rival = [[UILabel alloc] initWithFrame:CGRectMake(220,10,80,21)];
rival.tag = 103;
[cell.contentView addSubview:rival];
//[rival release];
UILabel *gamename = [[UILabel alloc] initWithFrame:CGRectMake(84,27,208,21)];
gamename.tag = 104;
[cell.contentView addSubview:gamename];
[gamename release];
UILabel *time = [[UILabel alloc] initWithFrame: CGRectMake(84,47,149,21)];
time.tag = 105;
[cell.contentView addSubview:time];
[time release];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(12,10,67,58)];
imageView.tag = 106;
[cell.contentView addSubview:imageView];
[imageView release];
}
UILabel *usr = (UILabel *)[cell viewWithTag:101];
usr.font = [UIFont boldSystemFontOfSize:12.0];
[usr setText:[appDelegate.usernames objectAtIndex:[indexPath row]]];
UILabel *stat = (UILabel *)[cell viewWithTag:102];
stat.font = [UIFont boldSystemFontOfSize:12.0];
[stat setText:[appDelegate.statistics objectAtIndex:[indexPath row]]];
NSURL *url = [NSURL URLWithString:[appDelegate.imagepaths objectAtIndex:[indexPath row]]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
UIImageView *imgView = (UIImageView *)[cell viewWithTag:106];
imgView.image = img;
UILabel *times = (UILabel *)[cell viewWithTag:105];
times.font = [UIFont boldSystemFontOfSize:12.0];
[times setText:[appDelegate.remainingtime objectAtIndex:[indexPath row]]];
UILabel *gamenames = (UILabel *)[cell viewWithTag:104];
gamenames.font = [UIFont boldSystemFontOfSize:12.0];
[gamenames setText:[appDelegate.challengenames objectAtIndex:[indexPath row]]];
UILabel *rivals = (UILabel *)[cell viewWithTag:103];
rivals.font = [UIFont boldSystemFontOfSize:12.0];
[rivals setText:[appDelegate.rivalusernames objectAtIndex:[indexPath row]]];
return cell;
}

IPhone UITableView jerky when scrolling

I'm loading my table from an XML feed in to an array then creating the cells as the code below shows. It can be really jerky when loading sometimes. I thought that was just the images downloading when I scroll but I removed them to test and sometimes it was still jerky. Can't work out what I'm doing wrong!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
const NSInteger BOTTOM_LABEL_TAG = 1002;
const NSInteger TEXT_FIELD_TAG = 1003;
UILabel *Labelcompanyname;
UILabel *Labeldistance;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell =
[[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier]
autorelease];
const CGFloat LABEL_HEIGHT = 15;
int spaceSize;
if(currentType == #"categorySearch"){
spaceSize = 57;
}
else {
spaceSize = 34;
}
Labelcompanyname =
[[[UILabel alloc]
initWithFrame:
CGRectMake(
spaceSize + 2.0 * cell.indentationWidth,
0.5 * (tableView.rowHeight - 2 * LABEL_HEIGHT)+10,
tableView.bounds.size.width -
spaceSize - 20.0,
LABEL_HEIGHT)]
autorelease];
[cell.contentView addSubview:Labelcompanyname];
Labeldistance =[[[UILabel alloc]
initWithFrame:
CGRectMake(
spaceSize + 2.0 * cell.indentationWidth,
0.5 * (tableView.rowHeight - 2 * LABEL_HEIGHT)+40,
tableView.bounds.size.width -
spaceSize - 20.0,
LABEL_HEIGHT)]
autorelease];
if(currentType == #"categorySearch") {
[cell.contentView addSubview:Labeldistance];
}
Labelcompanyname.tag = BOTTOM_LABEL_TAG;
Labelcompanyname.font = [UIFont systemFontOfSize:[UIFont labelFontSize] - 2];
Labeldistance.tag = TEXT_FIELD_TAG;
Labeldistance.font = [UIFont systemFontOfSize:[UIFont labelFontSize] - 2];
cell.backgroundView = [[[UIImageView alloc] init] autorelease];
cell.selectedBackgroundView = [[[UIImageView alloc] init] autorelease];
cell.textLabel.numberOfLines=0;
}
else
{
Labelcompanyname = (UILabel *)[cell viewWithTag:BOTTOM_LABEL_TAG];
Labeldistance = (UILabel *)[cell viewWithTag:TEXT_FIELD_TAG];
}
PromotionObject *newObj1;
newObj1=[totalArray objectAtIndex:indexPath.row];
if(!newObj1.furtherURL){
Labelcompanyname.text =[NSString stringWithFormat:#"%#", newObj1.companyname];
Labeldistance.text =newObj1.distance;
}
else
{
Labelcompanyname.text =[NSString stringWithFormat:#"Load more results"];
Labeldistance.text =#"";
}
NSURL *Imageurl = [NSURL URLWithString:[NSString stringWithFormat:#"%#", newObj1.locImage]];
NSData *data = [NSData dataWithContentsOfURL:Imageurl];
UIImage *img = [[[UIImage alloc] initWithData:data] autorelease];
if(currentType == #"categorySearch"){
cell.imageView.image = img;
} else if(currentType == #"fullSearch") {
cell.imageView.image = [UIImage imageNamed:#"newmap.png"];
} else {
cell.imageView.image = [UIImage imageNamed:#"business.png"];
}
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
Any help will be really appreciated
Tom
You definitely shouldn't do anything that blocks the UI thread for significant time while loading cells. E.g. NSData *data = [NSData dataWithContentsOfURL:Imageurl];.
I recommend loading your images into the data source in the background and reload/update the table/cells when the data has been downloaded. Would also be good to implement a cache for your images so you don't have to download them again everytime the cell is loaded.
If you need help with asynchronous image loading, search for that. Lot's of stuff on SO.
I guess you got your answer yourself. Your image loading blocks your UI from finishing the current cell request. tableView:cellForRowAtIndexPath: can't return until your image is fetched. I suggest you replace your image by an activity indicator and start to fetch your image in background. You might want to take a look at Concurrency Programming Guide

UITableView Accessory View not being displayed

Why is the following not displaying the proper UITableView accessory view? It is simply displaying the UIAcessoryTypeCheckmark that was selected in the nib file.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForManagedObject:(NSManagedObject *)managedObject withIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Selection";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = tvCell;
self.tvCell = nil;
}
self.tableView.rowHeight = 70.0f;
//Background
BOOL useDarkBackground = NO; //odd
if(indexPath.row %2 == 0) useDarkBackground = YES; //even
NSString *backgroundImagePath = [[NSBundle mainBundle] pathForResource:useDarkBackground ? #"DarkBackground" : #"LightBackground" ofType:#"png"];
UIImage *backgroundImage = [[UIImage imageWithContentsOfFile:backgroundImagePath] stretchableImageWithLeftCapWidth:0.0 topCapHeight:1.0];
cell.backgroundView = [[[UIImageView alloc] initWithImage:backgroundImage] autorelease];
cell.backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
cell.backgroundView.frame = cell.bounds;
//Checkmark
cell.userInteractionEnabled = YES;
NSString *checkmarkImagePath;
checkmarkImagePath = [[NSBundle mainBundle] pathForResource:[selectedObjects containsObject:managedObject] ? #"checkSelected" : #"checkUnselected" ofType:#"png"];
if([selectedObjects count] == 0) {
checkmarkImagePath = [[NSBundle mainBundle] pathForResource:#"checkUnselected" ofType:#"png"];
}
UIImage *checkmarkImage = [[UIImage imageWithContentsOfFile:checkmarkImagePath] stretchableImageWithLeftCapWidth:0.0 topCapHeight:1.0];
UIImageView *imageView = [[[UIImageView alloc] initWithImage:checkmarkImage] autorelease];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.frame = CGRectMake(10.0, 10.0, imageView.frame.size.width/1.2, imageView.frame.size.height/1.2);
return cell;
}
For some reason, the following does work:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *objectToChange = [[self fetchedResultsControllerForTableView:tableView] objectAtIndexPath:indexPath]; //The object
[tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *checkmarkImagePath = [[NSBundle mainBundle] pathForResource:[selectedObjects containsObject:objectToChange] ? #"checkSelected" : #"checkUnselected" ofType:#"png"];
UIImage *checkmarkImage = [[UIImage imageWithContentsOfFile:checkmarkImagePath] stretchableImageWithLeftCapWidth:0.0 topCapHeight:1.0];
UIImageView *imageView = [[[UIImageView alloc] initWithImage:checkmarkImage] autorelease];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.frame = CGRectMake(10.0, 10.0, imageView.frame.size.width/1.2, imageView.frame.size.height/1.2);
cell.accessoryView = imageView;
}
Thanks a lot!
It doesn't look like you're adding the UIImageView to the accessory view of the cell in the first code block.
You're also leaking all over the place. Make sure you adhere to the memory management guidelines set forth by Apple.
In your cellForRowAtIndexPath, you are not assigning the accessoryView to the cell, as you are in the didSelect method.

Iphone cellForRowAtIndexPath Jerky when scrolling asynchronously problem

I've released my app and noticed the jerkyness when scrolling in the CellForRowAtIndexPath, this is because i'm rendering an image from an JSON Feed via a URL. I've searched the internet and found a few examples and this one i've almost got working. The problem is when it renders the images don't match the correct title. Can someone please have a look and see what if i'm doing something obviously wrong.
Anyway here is my code:
- (void)displayImage:(UIImage *)image {
[photo setImage:image];
}
-(void)loadImage:(NSString *)url {
NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease];
[imageData release];
[self performSelectorOnMainThread:#selector(displayImage:) withObject:image waitUntilDone:NO];
}
CellForRowAtIndexPath Methord
#define DATELABEL_TAG 1 #define MAINLABEL_TAG 2 #define PHOTO_TAG 3 UIImageView *photo;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MainNewsCellIdentifier = #"MainNewsCellIdentifier";
UILabel *mainLabel, *dateLabel;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: MainNewsCellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier: MainNewsCellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
dateLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15.0,15.0,170.0,15.0)] autorelease];
dateLabel.tag = DATELABEL_TAG;
dateLabel.font = [UIFont systemFontOfSize:10.0];
dateLabel.textAlignment = UITextAlignmentLeft;
dateLabel.textColor = [UIColor darkGrayColor];
dateLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
[cell.contentView addSubview:dateLabel];
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15.0,28.0,170.0,60.0)] autorelease];
mainLabel.tag = MAINLABEL_TAG;
mainLabel.font = [UIFont boldSystemFontOfSize:14.0];
mainLabel.textColor = [UIColor blackColor];
mainLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
mainLabel.numberOfLines = 0;
[cell.contentView addSubview:mainLabel];
photo = [[[UIImageView alloc] initWithFrame:CGRectMake(190.0,15.0,85.0,85.0)] autorelease];
photo.tag = PHOTO_TAG;
photo.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:photo];
}
else {
dateLabel = (UILabel *)[cell.contentView viewWithTag:DATELABEL_TAG];
mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG];
photo = (UIImageView *)[cell.contentView viewWithTag:PHOTO_TAG];
}
NSUInteger row = [indexPath row];
NSDictionary *stream = (NSDictionary *) [dataList objectAtIndex:row];
NSString *title = [stream valueForKey:#"title"];
NSString *titleString = #"";
if( ! [title isKindOfClass:[NSString class]] )
{
titleString = #"";
}
else
{
titleString = title;
}
CGSize maximumSize = CGSizeMake(180, 9999);
UIFont *dateFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize dateStringSize = [titleString sizeWithFont:dateFont
constrainedToSize:maximumSize
lineBreakMode:mainLabel.lineBreakMode];
CGRect dateFrame = CGRectMake(15.0, 28.0, 170.0, dateStringSize.height);
mainLabel.frame = dateFrame;
mainLabel.text = titleString;
dateLabel.text = [stream valueForKey:#"created"];
NSString *i = [NSString stringWithFormat:#"http://www.domain.co.uk/images/stories/%#", [stream valueForKey:#"image"]];
photo.image = [UIImage imageNamed:#"i_digital_media.png"];
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self
selector:#selector(loadImage:)
object:i];
[queue addOperation:operation];
[operation release];
return cell;}
By the time that your image is loaded, the photo variable is pointed to a different photo :)
You need to pass both the loaded image and the UIImageView you want to update back - try using a NSDictionary to pass variables between threads :
- (void)displayImage:(NSDictionary *)info {
[[info objectForKey:#"photo"] setImage:[info objectForKey:#"image"]];
}
-(void)loadImage:(NSDictionary *)info {
NSString *imagePath = [info objectForKey:#"imagePath"];
UIImageView *photo = [info objectForKey:#"photo"];
// Load the image
NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease];
[imageData release];
// Pass it back to the main thread
NSDictionary *mainThreadInfo = [NSdictionary dictionaryWithObjectAndKeys:image, #"image", photo, #"photo", nil];
[self performSelectorOnMainThread:#selector(displayImage:) withObject:mainThreadInfo waitUntilDone:YES];
}
so now, your operation will pass the photo and the image data back to the main thread. Create the operation like this :
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:i, #"imagePath", photo, #"photo", nil];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self
selector:#selector(loadImage:)
object:info];
And get rid of the global photo variable :)

iPhone image memory leak

We have a code like this
NSData* imageData;
UIImage* imageForData;
UIImageView* imageView;
NSData* imageData;
UIImage* imageForData;
UIImageView* imageView;
CellWithId * cell = [[CellWithId alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier];
CGRect frame;
frame.origin.x = 5;
frame.origin.y = 0;
frame.size.height = 43;
frame.size.width = 52;
if ([[planDictionary objectAtIndex:indexPath.row] objectForKey:#"url"]!=[NSNull null]) {
imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[[planDictionary objectAtIndex:indexPath.row] objectForKey:#"url"]]];
imageForData = [[UIImage alloc] initWithData:imageData];
imageView = [[UIImageView alloc] initWithImage:imageForData];
imageView.frame = frame;
[cell.contentView addSubview:imageView];
[imageData release];
[imageForData release];
}NSData* imageData;
UIImage* imageForData;
UIImageView* imageView;
//CellWithId *cell = (CellWithId*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// if (cell == nil) {
CellWithId * cell = [[CellWithId alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier];
//}
CGRect frame;
frame.origin.x = 5;
frame.origin.y = 0;
frame.size.height = 43;
frame.size.width = 52;
if ([[planDictionary objectAtIndex:indexPath.row] objectForKey:#"url"]!=[NSNull null]) {
imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[[planDictionary objectAtIndex:indexPath.row] objectForKey:#"url"]]];
imageForData = [[UIImage alloc] initWithData:imageData];
imageView = [[UIImageView alloc] initWithImage:imageForData];
imageView.frame = frame;
[cell.contentView addSubview:imageView];
[imageData release];
[imageForData release];
}else {
//imageForData = [UIImage imageNamed:#"Plans-Default-image.jpg"];
imageForData = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Plans-Default-image" ofType:#"jpg"]];
imageView = [[UIImageView alloc] initWithImage:imageForData];
imageView.frame = frame;
[cell.contentView addSubview:imageView];
}
[imageView release];
I dont know what is the problem but imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[[planDictionary objectAtIndex:indexPath.row] objectForKey:#"url"]]]; is a place which always shows memory leaks. Please help me to debug this issue.
You allocate two CellWithIdand never release it. It looks as though you do not properly implement this method. The cell returned in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
should be autoreleased:
CellWithId * cell = [[[CellWithId alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
// ...
return (UITableViewCell *)cell;
Also you should use dequeueReusableCellWithIdentifier:CellIdentifierproperly to have decent performance.