IPHONE: UITableView cells not releasing content - iphone

I have this code below to populate my UITableView on the fly.
I have to display two kind of cells: a regular cell with a background image and a cell with a regular background image, plus a label and a button.
if Indexpath.row is less than a control variable, then regular cells are drawn. If not, cells with buttons and labels are drawn.
this is the code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
UIImage *imageU;
if (indexPath.row < controlVariable) {
imageU = [[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat: #"table%d", indexPath.row] ofType:#"jpg"]] autorelease];
cell.imageView.image = imageU;
} else {
imageU = [[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat: #"table-pg%d",numberX]
ofType:#"jpg"]] autorelease];
cell.imageView.image = imageU;
NSString * myString = [NSString stringWithFormat: #"pago%d", numberX];
UILabel * myLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 49.0, 200.0, 22.0)];
[myLabel setTextAlignment:UITextAlignmentLeft];
[myLabel setBackgroundColor:[UIColor blueColor]];
[myLabel setClipsToBounds:YES];
[myLabel setFont:[UIFont systemFontOfSize:14.0]];
[myLabel setTextColor:[UIColor blackColor]];
[myLabel setText: myString];
[myLabel setAlpha:0.6];
[cell addSubview: myLabel];
[myLabel release];
UIButton *buyButton = [[UIButton alloc] initWithFrame:CGRectMake( 220, 4, 100, 35)];
buyButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
buyButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[buyButton setTitle:NSLocalizedString(#"buyKey", #"") forState:UIControlStateNormal];
[buyButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
buyButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
UIImage *newImage = [[[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource: #"whiteButton" ofType:#"png"]] autorelease]
stretchableImageWithLeftCapWidth:12.0f topCapHeight:0.0f];
[buyButton setBackgroundImage:newImage forState:UIControlStateNormal];
[buyButton addTarget:self action:#selector(comprar:) forControlEvents:UIControlEventTouchDown];
buyButton.backgroundColor = [UIColor clearColor];
[buyButton setTag:indexPath.row];
[cell addSubview:buyButton];
[buyButton release];
}
return cell;
}
The problem with this code is: when I scroll the UITableView down and reach the division between regular cells and cells with buttons and labels, I see it is rendering correctly, but if I go up after going deep down, I see the buttons and labels being added to cells that were not supposed to have them. From this point forward, all cells contains buttons and labels...
It is like the cells are not releasing its contents before drawing. It is like labels and buttons are being added on top of other buttons and labels already on the cell. Cells are not releasing its contents before drawing again.
How to solve that?
thanks for any help.
NOTE: I see barely no difference after making the changes suggested by the two first answers. Now, not all cells are wrong, just some. They change every time I scroll down the table and return to the beginning of the table.

You should use a separate reuseIdentifier for each cell 'type' that you are using. In this case, you'll want to use two.
You'll also want to create/add the UILabel and UIButton when you get a dequeue miss and not for every run through.. In pseudocode:
UILabel * lbl;
UIButton * btn;
cell = [table dequeueReusableCellWithIdentifier:correctIdentifier];
if (cell == nil)
{
cell = ...; // alloc cell
lbl = ...;
lbl.tag = kTagLabel;
[cell addSubView:lbl];
btn = ...;
btn.tag = kTagButton;
[cell addSubView:btn];
}
else
{
lbl = (UILabel*)[cell viewWithTag:kTagLabel];
btn = (UIButton*)[cell viewWithTag:kTagButton];
}
//... now set the text/image appropriately.
Otherwise, you create a label and button each time the cell is dequeued from the table. Scrolling up and down will cause lots of labels and buttons to be created that never get released.

You should use two different reuseIdentifiers; one for cells with just images, and one for cells with images and buttons. The problem is that your one cell type is being reused, but its content is not (nor should it be) cleared out when it's dequeued.

Related

UIImageView in UITableView cell content view is not updating

In my iPhone application, I have a UITableView and this contains a UIImageView, button and Label. I am updating my database as per the values from the server and updating the details in the tableview. If I run the app for second time, after some modification at the server, the imageview is not getting updated. Button and label are updating. When I checked the local path for the image from the database, it shows the new image in the documents folder but the table cell still shows the old one. To the see the updated image, I should reinstall the app. What should I do to fix this issue?
Here is the work flow of what I did:
Loading new values from the database, and keeping all the values in an array
Removing the tableview
Creating the tableview again
Reload tableview.
Edit
//creating custom cell for the table view for displaying different objects
- (UIMenuItemCell *) getCellContentView:(NSString *)cellIdentifier {
CGRect CellFrame = CGRectMake(0, 0, 150, 60);
CGRect Label1Frame = CGRectMake(20, 23, 98, 30);
CGRect imgFrame = CGRectMake(20, 48, 110, 123);
CGRect btnFrame = CGRectMake(25, 136, 100, 30);
UILabel *lblTemp;
UIImageView *itemImg;
UIButton *itemBtn;
UIMenuItemCell *cell = [[UIMenuItemCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.frame = CellFrame;
//Initialize Label with tag 1.
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.tag = 1;
lblTemp.textColor=[UIColor colorWithRed:139.0f/255.0f green:69.0f/255.0f blue:19.0f/255.0f alpha:1.0f];
lblTemp.textAlignment = UITextAlignmentCenter;
lblTemp.backgroundColor = [UIColor clearColor];
lblTemp.font = [UIFont systemFontOfSize:13.0];
[cell.contentView addSubview:lblTemp];
[lblTemp release];
//Initialize ImageView
itemImg = [[UIImageView alloc]initWithFrame:imgFrame];
itemImg.tag = 2;
[cell.contentView addSubview:itemImg];
[itemImg release];
//Initialize Button
itemBtn = [[UIButton alloc]initWithFrame:btnFrame];
itemBtn.frame = btnFrame;
itemBtn.tag = 3;
itemBtn.titleLabel.textColor = [UIColor blueColor];
itemBtn.titleLabel.font = [UIFont systemFontOfSize:9.0];
[cell.contentView addSubview:itemBtn];
[itemBtn release];
return cell;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d", indexPath.row];
UIMenuItemCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [self getCellContentView:CellIdentifier];
cell.transform = CGAffineTransformMakeRotation(M_PI_2);
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.cellItemName = (UILabel *)[cell viewWithTag:1];
cell.cellitemImage = (UIImageView *)[cell viewWithTag:2];
cell.cellItemButton = (UIButton *)[cell viewWithTag:3];
DataBaseClass *itemObj = [appDelegate.itemArray objectAtIndex:indexPath.row];
NSString *imageLocalFilePath = nil;
if ([[tempitemStatusArray objectAtIndex:indexPath.row] isEqualToString:#"NotAvailable"]) {
cell.cellItemProgress.hidden = YES;
cell.cellItemButton.hidden = NO;
imageLocalFilePath = [NSString stringWithFormat:#"%#",[tempItemLocalNotAvailPath objectAtIndex:indexPath.row]];
NSString *date = [self changeDateFormat:itemObj.itemReleaseDate];
[cell.cellItemButton setTitle:date forState:UIControlStateNormal];
cell.cellItemButton.userInteractionEnabled = NO;
cell.userInteractionEnabled = NO;
[cell.cellItemButton removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents];
[cell.cellItemButton setBackgroundImage:[UIImage imageNamed:#"not_available_bttn_bck_img"] forState:UIControlStateNormal];
}else if ([[tempitemStatusArray objectAtIndex:indexPath.row] isEqualToString:#"Available"]){
cell.cellItemButton.userInteractionEnabled = YES;
cell.userInteractionEnabled = YES;
cell.cellItemProgress.hidden = YES;
[cell.cellItemButton setTitle:#"" forState:UIControlStateNormal];
[cell.cellItemButton setBackgroundImage:[UIImage imageNamed:#"available_bttn_img_normal"] forState:UIControlStateNormal];
[cell.cellItemButton setBackgroundImage:[UIImage imageNamed:#"available_bttn_img_pressed"] forState:UIControlStateHighlighted];
[cell.cellItemButton removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents];
[cell.cellItemButton addTarget:self action:#selector(confirmationAlert:) forControlEvents:UIControlEventTouchUpInside];
imageLocalFilePath = [NSString stringWithFormat:#"%#",[tempItemLocalAvailPath objectAtIndex:indexPath.row]];
}
if ([imageLocalFilePath isEqualToString:#""]) {
[cell.cellitemImage setImage:[UIImage imageNamed:#"item01.png"]];
}else {
[cell.cellitemImage setImageWithURL:[NSURL fileURLWithPath:imageLocalFilePath] placeholderImage:[UIImage imageNamed:#"item01.png"]];
}
cell.cellItemName.text = [NSString stringWithFormat:#"%#",[tempItemNameArray objectAtIndex:indexPath.row]];
}
return cell;
}
Please help.
I found the issue, in the cellForRowAtIndexPath method, for setting the image, I used the code
[cell.cellitemImage setImageWithURL:[NSURL fileURLWithPath:imageLocalFilePath] placeholderImage:[UIImage imageNamed:#"item01.png"]];
I used a external classes calls ImageLoading for loading the images and that classes included some cache methods, and that caused the issue. So I changed that line to
[cell.cellitemImage setImage:[UIImage imageWithContentsOfFile:imageLocalFilePath]];
that solved the issue.
Thanks for your support :)
There should be a
}
after the line
cell.cellItemButton = (UIButton *)[cell viewWithTag:3];
i took jet a first look at your code, and i found out this "error":
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d", indexPath.row];
so... it won't give you any error, it works...
but that's against how table works:
doing this you are creating and allocating a new cell for each item of your array/database,
meaning that if you need to scroll to see 1.000 items, you create 1.000 cells!!!
it shouldn't be like this.
Normally a table just creates only the cells needed to be shown on the screen/display
meaning that if your table area is 300 pixel in height and each cell is 30 pixel height,
then you may need only 11 cells, and you should use/allocate only 11 cells, not 1.000
the magic of cells is to reuse cells when user scrolls them out of screen (e.g. UP), to set it's data and images with the new item data and to put it again on screen (e.g. DOWN)
thats what CellIdentifier is normally used for, and it should be the same for all cells in a table (at least if all cells are similar, but the contained data, and you don't need different cells)
allocating too many cells could give you memory problems, if you manage too much items...
p.s.
i'm probably not answering to your question, there may be other problems in your code, as i said i just read it in hurry
you will have to keep some time delay between laoding your data from databse and tableview reload. you will then able to see the updated image.

UITableViewCell from cellForRowAtIndexPath has subview not updating

In my cellForRowAtIndexPath, I'm doing some custom formatting on a subview for when that cell is selected. The complete function is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIView *left;
UIImageView *leftImage;
UILabel *label;
ArticleButton *btn;
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (!cell)
{
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:#"UITableViewCell"] autorelease];
left = [[[UIView alloc] initWithFrame:CGRectMake(0, 2, 155, 139)] autorelease];
leftImage = [[[UIImageView alloc] initWithFrame:CGRectMake(7,9,141,77)] autorelease];
label = [[[UILabel alloc] initWithFrame:CGRectMake(6,87,141,48)] autorelease];
btn = [[[ArticleButton alloc] initWithFrame:CGRectMake(0,2,155,139)] autorelease];
left.tag = 0;
leftImage.tag = 1;
label.tag = 2;
btn.tag = 3;
[btn addTarget:self action:#selector(selectArticle:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:left];
[cell.contentView addSubview:leftImage];
[cell.contentView addSubview:label];
[cell.contentView addSubview:btn];
}
else
{
left = (UIView*)[cell viewWithTag:0];
leftImage = (UIImageView*)[cell viewWithTag:1];
label = (UILabel*)[cell viewWithTag:2];
btn = (ArticleButton*)[cell viewWithTag:3];
}
...load *entry
NSURL *url = [NSURL URLWithString:[entry imageUrl]];
FeedEntry* selectedEntry = [detailViewController detailItem];
NSString* selectedTitle = selectedEntry.title;
if ([selectedTitle isEqualToString:entry.title])
{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground_sel.png"]]]; <-- PROBLEM IS THIS IMAGE NEVER CHANGES
NSLog(#"selected row %#", selectedTitle);
}
else{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground2.png"]]];
}
[left setNeedsDisplay];
[leftImage setImageWithURL:url placeholderImage:[UIImage imageNamed:#"placeholder.gif"]];
[leftImage setContentMode:UIViewContentModeScaleAspectFill];
leftImage.clipsToBounds = YES;
[label setBackgroundColor:[UIColor clearColor]];
label.textColor = [UIColor whiteColor];
label.text = [entry.title stringByAppendingString:#"\n\n"];
label.numberOfLines = 3;
label.lineBreakMode = UILineBreakModeClip;
label.font = [UIFont fontWithName:#"Arial-BoldMT" size:12];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
The problem I'm having is with this section:
if ([selectedTitle isEqualToString:entry.title])
{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground_sel.png"]]];
NSLog(#"selected row %#", selectedTitle);
}
else{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground2.png"]]];
}
Everything else works, but although I'm logging that it gets called, but the background of my subview to indicate that the row in question is a selected row, never changes. I've tried calling setNeedsDisplay, I've tried scrolling up and down trying to get the cells to dequeue and get recreated, it just never users the other image, even though it logs that the row being drawn was a selected row.
(Once I get this working, I need to implement the "right" section to have two "cells" in the one row and only one will be selected. That's why I'm doing it this way with subviews in the cell).
What am I doing wrong?
I think it is a problem to set the tag to zero. The documentation says:
viewWithTag:
Return Value
The view in the receiver’s hierarchy whose tag property matches the value in the tag parameter.
Discussion
This method searches the current view and all of its subviews for the specified view.
If think that most views tag is zero, even that of the current cell's view. I think that you dont get the correct view out of it. Try not to use 0 as a tag to work with.
Whenever a particular UITableViewCell is selected, this particular delegate is called -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Try to see if your button taps are being first responded by this delegate rather than going to selectArticle: selector you have defined...
Instead of setting this in tableview:cellForRowAtIndexPath:, try doing it in the tableview:willSelectRowAtIndexPath:
See the protocol reference for further details.

add label on cell in table view and access it on buttonClicked Method.....:)

i am a new Programmer.... i wants add two labels on cell in table view.....and access the label.text in buttonClicked method.....
i am new programmer..so i don't know add label on table cell.... is I am right?
thanks in advance...for giving your valuable time for my code....:)
///insert individual row into the table view
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:#"Cell %i",indexPath.section]];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:[NSString stringWithFormat:#"Cell %i",indexPath.section]] autorelease];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;//my code.... change the color or selected cell
search_items *pro = [searchCount objectAtIndex:[indexPath row]];
/// i wants access these two labels on buttonClicked Method...
UILabel *showroomName = [[UILabel alloc] initWithFrame:anySize];
[showroomName setText:pro.s_showroomName];
[cell addSubview:showroomName];
[showroomName release];
UILabel *productName = [[UILabel alloc] initWithFrame:anySize];
[productName setText:pro.s_productName];
[cell addSubview:productName];
[productName release];
UIButton* aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
aButton.frame = CGRectMake(150, 15,150,40);
[aButton setTag:indexPath.row];
[aButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:aButton];
UIImage *img = [UIImage imageNamed:#"image.png"];
[aButton setImage:img forState:UIControlStateNormal];
[aButton setTitle:#"View Details" forState:UIControlStateNormal];
[aButton addSubview:buttonLabel1];
NSString *filepath=[[NSBundle mainBundle]pathForResource:pro.s_image ofType:#"png"];
UIImage *image=[UIImage imageWithContentsOfFile:filepath];
cell.imageView.image=image;
return cell;
}
-(void)buttonClicked:(UIButton*)sender {
//int tag = sender.tag;
}
UILabel *showroomName = [[UILabel alloc] initWithFrame:anySize];
[showroomName setText:pro.s_showroomName];
cell.accessoryView = showroomName;
Try this for memory management: Alloc the label in a method that gets called a single time (like viewDidLoad, viewWillAppear, viewDidAppear, init, even numberOfSectionInTableView) and just change it's text or whatever you want to change in cellForRowAtIndexPath. This way, you will not have leaks, bad memory management or useless memory allocated. And also, be very careful with realeasing. You should release the objects when you are sure that you won't need those. Some objects might still need them after you release them.

uitableview gets crashed while scrolling in ipad

hi all i implemented customized UITableViewcell with the below code.Each cell loaded with four images..
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *hlCellID = #"hlCellID";
UITableViewCell *hlcell = [tableView dequeueReusableCellWithIdentifier:hlCellID];
if(hlcell == nil) {
hlcell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:hlCellID] autorelease];
hlcell.accessoryType = UITableViewCellAccessoryNone;
hlcell.selectionStyle = UITableViewCellSelectionStyleNone;
[hlcell.contentView removeAllSubViews];
}
//NSLog(#"the scetions is %#",sections);
int section = indexPath.section;
for(int i=0;i<4;i++){
CGRect rect = CGRectMake(18+192*i, (4*indexPath.row)+50, 120, 150);
if ((4*indexPath.row)+i>=[self.imagesToDisplay count]) {
break;
}
UIImage *imageToDisplay=[UIImage imageWithData:[self.imagesToDisplay objectAtIndex:(4*indexPath.row)+i]];
NSLog(#"The size of the image is:%#",NSStringFromCGSize(imageToDisplay.size));
UIButton *button=[[UIButton alloc] initWithFrame:rect];
[button setFrame:rect];
[button setBackgroundImage:imageToDisplay forState:UIControlStateNormal];
[button setContentMode:UIViewContentModeCenter];
NSString *tagValue = [NSString stringWithFormat:#"%d%d",indexPath.row,i];
NSLog(#"the tag is %#",tagValue);
button.tag = [tagValue intValue];
NSLog(#"....tag....%d", button.tag);
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[hlcell.contentView addSubview:button];
[button release];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(18+192*i,(4*indexPath.row)+100+70 , 100, 100)] ;
label.text = #"price $0.99";
label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [UIFont fontWithName:#"ArialMT" size:12];
[hlcell.contentView addSubview:label];
[label release];
}
return hlcell;
}
for each image acts as uibutton.i am trying to load around 1000 images.these images i am taking from the server.when one image is loaded to my app i am updating total cell.
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:ceil((float)[gridView.imagesToDisplay count]/4)-1 inSection:0];
NSArray *cellIndexPath=[NSArray arrayWithObjects:indexPath,nil];
[gridView.tableview reloadRowsAtIndexPaths:cellIndexPath withRowAnimation:UITableViewRowAnimationNone];
upto now my code is working fine and when i am trying to scroll many times after loading all the images its getting crash.and my GDB showing as memory warning.can any one suggest me why the issue happening.Thanks for your response in advance.
It looks like you always allocate new Images and display them on the Cell, but you never actually release the images when the cell is no longer displayed.
The definition for the UITableView cell states, that as soon a cell is no longer used it is purged and prepared for a new content. In your code you always add new subviews to the cell, but never actually release the content.
The best solution to your problem is to implement a UITableViewCell by subclassing it and manually set the images. Furthermore implement the
- (void)prepareForReuse
method of the class to release the images that are currently displayed. See the reference for more documentation of UITableViewCell

iOS: UITableView reloadData not working

I have a UITableView with two sections: free and paid. Each section has a different kind of cell. The free cells have two labels and an image. The paid cells has two labels, an image and a button that allows the product to be bought. Once a product is bought, the BUY button on that particular cell must not be shown again. Said that, this is how the cells are initialized...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *IDNormal = #"Normal";
static NSString *IDComplex = #"Complex";
if (indexPath.section == 0) { // show free objects
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:IDNormal];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:IDNormal] autorelease];
// product description
UILabel * labelDescription = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 54.0, 225, 18)];
[labelDescription setTextAlignment:UITextAlignmentLeft];
[labelDescription setBackgroundColor:[UIColor whiteColor ]];
[labelDescription setClipsToBounds:YES];
[labelDescription setFont:[UIFont systemFontOfSize:14.0]];
[labelDescription setTextColor:[UIColor blackColor]];
[labelDescription setAlpha:0.6];
[labelDescription setTag: 860];
[cell addSubview:labelDescription];
[labelDescription release];
// this will show the word FREE on free objects (cells)
UILabel * labelFREE = [[UILabel alloc] initWithFrame:CGRectMake(235.0, 54.0, 80, 18)];
[labelFREE setTextAlignment:UITextAlignmentCenter];
[labelFREE setBackgroundColor:[UIColor greenColor ]];
[labelFREE setClipsToBounds:YES];
[labelFREE setFont:[UIFont boldSystemFontOfSize:14.0]];
[labelFREE setTextColor:[UIColor blackColor]];
[labelFREE setAlpha:0.75];
[labelFREE setText:NSLocalizedString(#"freeKey", #"")];
[labelFREE setTag: 861];
[cell addSubview:labelFREE];
[labelFREE release];
}
cell.imageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat: #"free%d", indexPath.row] ofType:#"jpg"]];
NSString * prefixLabel = [NSString stringWithFormat: #"gratis%d", indexPath.row];
UILabel *labelDescription2 = (UILabel*)[cell viewWithTag:860];
[labelDescription2 setText:#"FREE"];
return cell;
} else { // show paid objects
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:IDComplex];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:IDComplex] autorelease];
UILabel * labelDescription = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 54.0, 225, 18)];
[labelDescription setTextAlignment:UITextAlignmentLeft];
[labelDescription setBackgroundColor:[UIColor whiteColor ]];
[labelDescription setClipsToBounds:YES];
[labelDescription setFont:[UIFont systemFontOfSize:14.0]];
[labelDescription setTextColor:[UIColor blackColor]];
[labelDescription setAlpha:0.6];
[labelDescription setTag: 1];
[cell addSubview:labelDescription];
[labelDescription release];
}
int numberPaidObject = indexPath.row + 500;
cell.imageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat: #"table-pg%d", numberPaidObject] ofType:#"jpg"]];
NSString * nomeDoProduto = [NSString stringWithFormat: #"paid%d", numberPaidObject];
if ( NotSoldProduct ) {
NSString * prefixoEtiqueta = [NSString stringWithFormat: #"paid%d", numberPaidObject];
UILabel *labelDescription2 = (UILabel*)[cell viewWithTag:1];
[labelDescription2 setText:[description objectAtIndex: numberPaidObject ];
}
return cell;
}
}
as I have to identify which BUY button was clicked and I am using dequeueReusableCellWithIdentifier, so I have to use the following method...
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
int numeroOfPaidObject = indexPath.row + 500;
if ((indexPath.section == 1) && ObjectForSale) {
// if paid objects and object was not bought yet
// in theory this section will not be executed if the object was already bought and paid
// so, I am skipping the BUY button creation and, in theory the cell will not have a BUY
// button… the problem is that it does...
UIButton * buyButton = [[UIButton alloc] initWithFrame:CGRectMake( 235, 45, 80, 30)];
buyButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
buyButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[buyButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
buyButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
buyButton.backgroundColor = [UIColor clearColor];
[buyButton addTarget:self action:#selector(buyNow:) forControlEvents:UIControlEventTouchDown];
[buyButton setTitle:NSLocalizedString(#"buyKey", #"") forState:UIControlStateNormal];
UIImage *newImage = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
pathForResource: #"whiteButton" ofType:#"png"]]
stretchableImageWithLeftCapWidth:12.0f topCapHeight:0.0f];
[buyButton setBackgroundImage:newImage forState:UIControlStateNormal];
[buyButton setTag: numeroOfPaidObject];
[cell addSubview:buyButton];
[buyButton release];
}
}
The problem with this code is: when I reload table's data the BUY button continues to show up on all cells, including those that was already bought by the user.
Any ideas?
thanks for any help.
You can step through it with the debugger, but here is my guess:
Because table cells are being reused, eventually all of the already purchased items end up in table cells that were previously occupied by an unpurchased item and therefore have had a buy button added to them.
If this is the case you need to add an else clause in your second section of code that deletes the button from the cell if the product has already been purchased.
Another problem is that your code is adding a new button every time a cell is displayed, so many/most of your cells probably have several buttons in them.
You will want to refactor your code so that the button is added once, in tableView:cellForRowAtIndexPath:, and only for newly-created cells.
There are two ways to do that:
Split the "Complex" cell type into two types: purchased and unpurchased, and create/dequeue them separately. Add the button only to to the unpurchased cell type.
Add the buttons to all of the cells in the "paid" section, and hide it when the item has been purchased.
In either case you'll need a way to grab a pointer to the button. The preferred way to do this is with the tag property, making it a one liner:
UIButton * button = [cell viewForTag:42];
...
You can also iterate through the subviews of the cell looking for UIButton objects:
UIButton *button = nil;
foreach (UIView *view in cell.subviews) {
if ([view isKindOfClass:[UIButton class]])
button = (UIButton *)view;
}
I would suggest using a constant tag to identify the button, and then rewrite your buyNow: method as follows:
-(IBAction)buyNow:(id)sender {
UITableViewCell *cell = (UITableViewCell *)((UIView *)sender).superview;
int itemID = [tableView indexPathForCell:cell].row + 500;
...
}
Perhaps I am thinking too simply here but a table view will function just fine with only the delegates set, but will fail to respond to reloadData if you have not made the connection in IB, did you check that?