I have a UITableView that exceeds the screen region. I display some data from an NSMutableArray which is filled with NSDictionary objects. The objects all have a group property which is true or false, if group is true a UIButton should be displayed in the cell (to expand the group).
I created a UIButton in my cell prototype in storyboard. I gave it alpha 0. If I load the list the button is not in any cell (duh). This is in my cellForRowAtIndexPath:
if ([[contacts[indexPath.section] valueForKey:#"group"] isEqualToString:#"true"]) {
UIButton *button = (UIButton*)[cell viewWithTag:999];
[button setAlpha:1.0f];
}
If the group property is true make the button visible. In my current test case the first three objects have group set to true, the rest have group set to false. Now my problem is, the first three cells have a visible button (as intended), but some cells further along the table have one as well. I put a breakpoint in the above if statement, and it really goes in there only three times.
It happens in a pattern, the first three cells have a button, than five cells don't and than another three have a visible button. Than another five have no button and the last cell does (I think if I add two cells they will also have a button)
The second group of cells that have a button starts just outside the screen, so that may have something to do with it.
One more relevant thing, There is also some text displayed that I take from the same array as the group flag, this text is displayed correct. So it's not that the cells are duplicated somehow, it's just the if statement part that screws up.
I double checked the amount of times the program goes into the if statement and it's really only three times (the first three entries). If I comment the setAlpha call on the button no buttons appear anywhere, so there is also no other place where the button can become visible.
I'm testing on an iPad 4 with iOS 7.1.
If I decrease the height of my rows so all of them fit in the screen, the problem is gone, so It's definitely related to rows falling outside the screen region while loading the data.
edit
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
UIColor *color = [UIColor colorWithRed:(1.0f/255.0f)*220 green:(1.0f/255.0f)*220 blue:(1.0f/255.0f)*225 alpha:1.0f];
if (indexPath.row == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"single" forIndexPath:indexPath];
UILabel *screenname = (UILabel*)[cell viewWithTag:10];
UILabel *username = (UILabel*)[cell viewWithTag:11];
UIImageView *avatar = (UIImageView*)[cell viewWithTag:20];
if ([[contacts[indexPath.section] valueForKey:#"group"] isEqualToString:#"true"]) {
NSDictionary *c = contacts[indexPath.section];
UIButton *button = (UIButton*)[cell viewWithTag:999];
[button setAlpha:1.0f];
button.tag = indexPath.section;
[button addTarget:self action:#selector(onGroupButtonClick:) forControlEvents:UIControlEventTouchUpInside];
int numUsersInGroup = [[c valueForKey:#"users"] count];
NSString *numUsersInGroupString = [NSString stringWithFormat:#"%d",numUsersInGroup];
[button setTitle:numUsersInGroupString forState:0];
[button setNeedsDisplay];
screenname.text = #"Groep";
username.text = [NSString stringWithFormat:#"%#",[c valueForKey:#"groupName"]];
} else {
User *c = (User*)contacts[indexPath.section];
UIButton *button = (UIButton*)[cell viewWithTag:999];
[button setAlpha:0.0f];
screenname.text = [NSString stringWithFormat:#"%#",[c valueForKey:#"screenName"]];
username.text = [NSString stringWithFormat:#"%#",[c valueForKey:#"username"]];
[avatar setImage:[UIImage imageNamed:#"avatar.png"]];
}
[GeneralFunctions setFontFamily:#"KozGoPro-ExtraLight" forView:cell andSubViews:YES];
[GeneralFunctions setFontFamily:#"KozGoPro-Medium" forView:screenname andSubViews:YES];
[cell.layer setShadowColor:[color CGColor]];
[cell.layer setShadowOffset:CGSizeMake(0,4)];
[cell.layer setShadowRadius:3.0f];
[cell.layer setShadowOpacity:1.0f];
cell.clipsToBounds = NO;
cell.layer.masksToBounds = NO;
}
if (indexPath.row > 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"group" forIndexPath:indexPath];
UILabel *screenname = (UILabel*)[cell viewWithTag:10];
UILabel *username = (UILabel*)[cell viewWithTag:11];
User *c = (User*)[contacts[indexPath.section] valueForKey:#"users"][indexPath.row-1];
screenname.text = [NSString stringWithFormat:#"%#",[c valueForKey:#"screenName"]];
username.text = [NSString stringWithFormat:#"%#",[c valueForKey:#"username"]];
[GeneralFunctions setFontFamily:#"KozGoPro-ExtraLight" forView:cell andSubViews:YES];
[GeneralFunctions setFontFamily:#"KozGoPro-Medium" forView:screenname andSubViews:YES];
}
return cell;
}
When your cell is reused you are not setting the button back to the 0.0 alpha. You need to reset your cell or change your cell's property whenever you reuse a cell otherwise it'll show the old content
if ([[contacts[indexPath.section] valueForKey:#"group"] isEqualToString:#"true"]) {
NSDictionary *c = contacts[indexPath.section];
UIButton *button = (UIButton*)[cell viewWithTag:999];
[button setAlpha:1.0f];
//this line changes your tag and hence in else condition for reused cell it'll come nil
button.tag = indexPath.section;
} else {
UIButton *button = (UIButton*)[cell viewWithTag:999];
[button setAlpha:0.0f];
}
Suggestion instead of accessing button by tag access it by using property by type casting the cell into your custom cell
Related
I am trying to set up some UIButtons and UILabels in my custom UITableViewCell. For each row in the table I have 4 buttons with user profile images and below each button is a label displaying the username. Images and usernames are taken from Parse.com. I have a friends array of size 34, and I am displaying 9 rows so the last two buttons and label must be hidden. The code below works but for some reason when I scroll up the table some of the other rows will also hide their two rightmost buttons and labels. I'm wondering if my logic for loading images from the array is incorrect. Not sure what's going on here. Any advice would be greatly appreciated.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
FriendViewCell *cell = (FriendViewCell *)[tableView dequeueReusableCellWithIdentifier:#"friendCell" forIndexPath:indexPath];
for (int i = 0; i < 4; i++) {
if ((int)indexPath.row * 4 + i < [self.currentUser.friends count]) {
UIButton *button = cell.buttons[i];
[button setTag:(int)indexPath.row * 4 + i];
button.layer.cornerRadius = button.frame.size.width / 2;
button.clipsToBounds = YES;
UILabel *label = cell.labels[i];
[button addTarget:self action:#selector(friendTapped:) forControlEvents:UIControlEventTouchUpInside];
//here we need to decide what to access
PFUser *user = self.currentUser.friends[(int)indexPath.row * 4 + i];
label.text = user.username;
PFFile *userImageFile = user[#"profilePic"];
[userImageFile getDataInBackgroundWithBlock: ^(NSData *imageData, NSError *error) {
if (!error) {
UIImage *image = [UIImage imageWithData:imageData];
[button setBackgroundImage:image forState:UIControlStateNormal];
}
}];
}
else {
UIButton *button = cell.buttons[i];
[button setEnabled:NO];
[button setHidden:YES];
UILabel *label = cell.labels[i];
[label setHidden:YES];
}
}
return cell;
}
You can try by unhiding the button and Label in your first conduction like:
if ((int)indexPath.row * 4 + i < [self.currentUser.friends count]) {
[button setEnabled:YES];
[button setHidden:NO];
[label setHidden:NO];
// Other code
}
else{
......
}
The 'iOS' way to handle this would be to fill out the prepareForReuse method of your custom cell. This is where you should be reseting various attributes on cells that may be reused by the caching system.
Apple Docs
-prepareForReuse
Prepares a reusable cell for reuse by the table view's delegate.
Discussion
If a UITableViewCell object is reusable—that is, it has a reuse identifier—this method is invoked just before the object is returned from the UITableView method dequeueReusableCellWithIdentifier:. For performance reasons, you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state. The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell. If the cell object does not have an associated reuse identifier, this method is not called. If you override this method, you must be sure to invoke the superclass implementation.
I'm experiencing a problem with regards to adding a button to a tableview cell. Basically, I'm adding a button to a specific cell, but that button also appears on random other cells (not currently in the view).
When I tap a cell, I set a variable (tappedCell=indexPath), and reload that cell. In my cellForRowAtIndexPath I check if the indexPath is equal to the tappedCell, and if it is I add a button to it. That works, but this button also appears on other cells further down in the tableView. These cells are not in the view when I tap it, but further down, so I have to scroll to see them. If I keep scrolling up and down (quickly), more and more cells with buttons appears. This seems to be completely random.
I've tried adding a NSLog() inside the if-statement where I add the button, but this is not called more than once (when I tap the original cell). So it's actually not adding more buttons, it has to be the same one appearing in multiple cells.
I have no idea why this is happening. I've tried adding a button to every cell, and then just set hidden = YES as standard, and hidden = NO when the [self.tappedCell isEqual:indexPath], but this does not change anything...
Here you can see the code I use to add the button to my cell:
UIButton *newBtn=[UIButton buttonWithType:UIButtonTypeCustom];
[newBtn setImage:[UIImage imageNamed:#"open.png"] forState:UIControlStateNormal];
[newBtn setFrame:CGRectMake(220, 0, 100, 86)];
[newBtn addTarget:self action:#selector(openImage:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:newBtn];
I don't know what I'm doing wrong, or if I am doing something wrong at all. It's worth mentioning that I'm using a standard Apple/iOS style=subtitle cell, and not a custom one. This is to keep it consistent throughout my app (The cells are made in the storyboard, and I'm reusing a prototype cell).
Could anyone give me any insight on why it's behaving like it does, and how I can fix it?
Thanks in advance!
EDIT 1:
Here's my full code for cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Set up the item
XYZItem *item = [self.itemsInView objectAtIndex:indexPath.row];
NSString *CellIdentifier = #"itemPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = item.itemName;
if ([self.selectedItem isEqual:indexPath])
{
cell.textLabel.numberOfLines = 2;
UIButton *newBtn=[UIButton buttonWithType:UIButtonTypeCustom];
[newBtn setImage:[UIImage imageNamed:#"open.png"] forState:UIControlStateNormal];
[newBtn setFrame:CGRectMake(220, 0, 100, 86)];
[newBtn addTarget:self action:#selector(openImage:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:newBtn];
}
NSString *detailTextLabelText = [NSString stringWithFormat:#"%lu subitems", (unsigned long)[item.subItems count]];
cell.detailTextLabel.text = detailTextLabelText;
return cell;
}
The button is showing up on cells that have reused a button that previously added it.
There are a few options here.
Make the button part of every cell. Set it's .hidden property every time you create/reuse one to the appropriate value.
Remove the button in the cell's prepareForReuse method.
Assuming self.tappedCell is a UITableViewCell subclass and indexPath is an index path, [self.tappedCell isEqual:indexPath] will always return NO
I faced same issue and i also had multiple headers:
The solution is:
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
headerLabel = [[UILabel alloc] initWithFrame:
CGRectMake(15, 5, self.tableView.frame.size.width, 15.0)];
headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.textAlignment = NSTextAlignmentLeft;
[headerLabel setFont:[UIFont fontWithName:#"Helvetica Neue Medium" size:13.0]];
headerLabel.tag = 1002;
[cell.contentView addSubview:headerLabel];
button = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, HEIGHTROW)];
[button addTarget:self action:#selector(eventAddAlert) forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:[UIImage imageNamed:#"add_manually.png"] forState:UIControlStateNormal];
button.hidden = YES;
button.tag = 1001;
[cell.contentView addSubview:button];
}else{
// use viewWithTag to find lblNombre in the re-usable cell.contentView
headerLabel = (UILabel *)[cell.contentView viewWithTag:1002];
button = (UIButton *)[cell.contentView viewWithTag:1001];
}
if(indexPath.section == 0 && indexPath.row == 0){
button.hidden = NO;
}else{
button.hidden = YES;
.........
}
.........
Yesterday I asked a question about a cell not showing correctly a button that depends on a string value. Please take a look at it if you want: Strange behaviour on table view with core data.
User #jrturton pointed out following as part of his answer:
A reused cell will have the subview added every time - so there could
be many urgent views on top of each other. The cell should only ever
add this once and keep it in a property
I think that this answer marks the correct direction I must follow to solve my issue, but I am not able to implement the answer into my code which is following:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
NSString *isUrgent = [[managedObject valueForKey:#"urgent"]description];
[[cell textLabel] setText:[[managedObject valueForKey:#"thingName"] description]];
//urgent
if ([isUrgent isEqual:#"Urgent"]){
UIButton *urgentButton = [[UIButton alloc]initWithFrame:CGRectMake(71, 27, 18, 18)];
[urgentButton setImage:[UIImage imageNamed:#"urgent-3"]forState:UIControlStateNormal];
[cell addSubview:urgentButton];
NSLog(isUrgent);
}
//not urgent
if ([isUrgent isEqual:#"Not urgent"]){
UIButton *urgentButton = [[UIButton alloc]initWithFrame:CGRectMake(71, 27, 18, 18)];
[urgentButton setImage:[UIImage imageNamed:nil]forState:UIControlStateNormal];
[cell addSubview:urgentButton];
NSLog(isUrgent);
}
[[cell detailTextLabel] setText:#" "];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.textLabel.textColor = [UIColor blueColor];
cell.textLabel.font = [UIFont fontWithName:#"Noteworthy" size:22.0f];
cell.detailTextLabel.font = [UIFont fontWithName:#"Noteworthy" size:15.0f];
}
The behaviour of the cell must be following:
1. If isUrgent = #"Urgent", the cell must show urgentButton (including imageNamed:#"urgent-3":
2. Else no button has to be shown.
The current behaviour is as follows:
1. If isUrgent = #"Urgent", the cell shows urgentButton (including imageNamed:#"urgent-3".
2. If isUrgent = #"Not urgent", value tested in NSLog, the cell shows urgentButton too.
This behavior only happens when the cell has changed its isUrgent value at least one time.
I need your help to implement the above mentioned answer. Thank you.
I agree with #wuii, but I think the answer can be clearer. The idea is that reused cells have their view hierarchy already built, so it's harmful to do it again each time a cell is reused (which is all of the time during scrolling). The advice can be encapsulated in a "lazy getter" that returns the cell's urgent button.
// above #implementation
#define kURGENT_BUTTON_TAG (256)
- (UIButton *)urgentButtonInCell:(UITableViewCell *)cell {
UIButton *urgentButton = (UIButton *)[cell viewWithTag:kURGENT_BUTTON_TAG];
if (!urgentButton) {
urgentButton = [[UIButton alloc]initWithFrame:CGRectMake(71, 27, 18, 18)];
urgentButton.tag = kURGENT_BUTTON_TAG;
[cell addSubview:urgentButton];
}
return urgentButton;
}
Now your configureCell can just ask for the button:
UIButton *urgentButton = [self urgentButtonInCell:cell];
UIImage *image = ([isUrgent isEqualToString:#"Urgent"])? [UIImage imageNamed:#"urgent-3"] : nil;
[urgentButton setImage:image forState:UIControlStateNormal];
You will need to keep track of your cell is reused or it's fresh one.
What here might be happening is you are adding UIButton to reused cell, but it already has button having "urgent-3" image set
Do this
Pass one more BOOL parameter to configure cell isFreshCell with value set as per new cell or not.
**
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
isFreshCell = NO;
if(cell==nil)
{
isFreshCell = YES;
cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath isFreshCell:isFreshCell];
New method signature
-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath isFreshCell:(BOOL) isFreshCell
2 When you add button set some tag to it.
3 If isFreshCell is false dont add new button as it is already there and you can access this button using subviewWithTag method like this cell.contentView.subviewWithTag and then set image or set nil image or just hide button
I have code here that generates a list of cells that contain buttons.
I'm pretty sure there is a way to make it so that I am creating 1 button object instead of 20, but I'm not quite sure how to implement that?
I need some guidance as to where to make it so I only create 1 button object.
Additionally, I might be making 20 cell objects when I only need 1 as well?
I don't totally understand how to utilize memory well yet.
My code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"TimesCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//[cell sizeToFit];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if([cell.contentView viewWithTag:3] != nil){
[[cell.contentView viewWithTag:3] removeFromSuperview];
}
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(customActionPressed:)
forControlEvents:UIControlEventTouchDown];
[button setTitleEdgeInsets:UIEdgeInsetsMake(-10.0f, 0.0f, 0.0f, 0.0f)];
button.frame = CGRectMake(5, 5, 310, 50);
button.tag = 3;
int rows = [yourDefaultActivities count];
int rowsl = rows - 1;
float r = 1+(((255-1+75)/rowsl)*(indexPath.row));
if(r > 255){
r = 255;
}
float g = 255-(((255-1+75)/rowsl)*(indexPath.row));
if(g < 0){
g = 255-fabsf(g);
}else{
g = 255;
}
float b = 1;
UIColor *thisColor = [UIColor colorWithRed:r/255 green:g/255 blue:b/255 alpha:1];
button.backgroundColor = thisColor;
button.clipsToBounds = YES;
button.layer.cornerRadius = 15;
button.titleLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:14];
[button setTitle:[[yourDefaultActivities objectAtIndex:indexPath.row] objectAtIndex:0] forState:UIControlStateNormal];
[button.titleLabel setTextColor:[UIColor blackColor]];
[button.titleLabel setFont:[UIFont fontWithName:#"HelveticaNeue" size:14]];
[cell addSubview:button];
return cell;
}
EDIT: I tried to remove the buttons every time I created a new one, but I must be doing it wrong..
One button object can't appear in 8 cells at once -- you do need as many cells and buttons as will fit on the screen at any time (it looks like 8 or 9). But 8 or 9 cell with buttons in them should not cause any memory problems -- buttons aren't that expensive. The problem with the code you posted though, is that it is adding buttons every time cellForRowAtIndexPath is called, which happens a lot when you scroll. Since cells are reused, you don't want to be adding a button to a cell that already has one. The easiest solution, in my opinion, is to make a custom cell in the storyboard, and add you buttons there. You can still set their color in code based on the indexPath so you get the look you want. Alternately, you can check whether the cell (actually the cell.contentView which is where you should be adding them, not directly to the cell) has a subview of class UIButton, and only add a button if it doesn't already have one.
After Edit:
In answer to your comment, you don't need to make the rounded button in the storyboard, you can just add a button (type custom) to your subclassed cell, and then modify its look in code. Here is an example of what I mean. In this test app, I created a custom cell class (RDCell) and changed the class of the cell in the storyboard to that. I added a custom button to the cell, positioned and sized it with constraints, and made an IBOutlet to it in RDCell.h. Here is what I have in the table view controller:
#import "TableController.h"
#import "RDCell.h"
#implementation TableController
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(RDCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.button.backgroundColor = [UIColor colorWithHue:.15 + (indexPath.row/30.0) saturation:1 brightness:1 alpha:1];
cell.button.layer.cornerRadius = 15;
cell.button.titleLabel.textColor = [UIColor blackColor];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
RDCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
[cell.button addTarget:self action:#selector(customActionPressed:) forControlEvents:UIControlEventTouchUpInside];
cell.button.tag = indexPath.row;
return cell;
}
-(void)customActionPressed:(UIButton *) sender {
NSLog(#"button pressed in row: %d",sender.tag);
[self.tableView reloadRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:sender.tag inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
}
This was the resultant view:
I put a log in initWithCoder for RDCell, and it's called only 12 times (the max. number of cells on the screen at any one time), so there's never more than 12 cells or 12 buttons.
I'm having some problem with UIButton in a UITableViewCell.
I have created a custom tableviewcell in storyboard, using the prototype cell.
There are two buttons and I have set a tag to them.
The first time the table view is drawn everything is displayed correct, but if I scroll or update the data and call reloadData on tableview, it's not updated correct.
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Moment Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSLog(#"Cell: %#", cell);
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
NSArray *row = [mMoment objectAtIndex:indexPath.row];
UILabel *label;
label = (UILabel *)[cell viewWithTag:101];
label.text = [row objectAtIndex:0];
label = (UILabel *)[cell viewWithTag:102];
label.text = [NSString stringWithFormat:#"Koeff: %#",[row objectAtIndex:2]];
UIButton *button;
NSString *btn_title;
button = (UIButton *)[cell viewWithTag:104];
NSLog(#"Button: %#", button);
[button setTag:1];
btn_title = [NSString stringWithFormat:#"%#", [row objectAtIndex:4]];
[button setTitle:btn_title forState:(UIControlState)UIControlStateNormal];
[button addTarget:self action:#selector(poangButtonClick:event:) forControlEvents:UIControlEventTouchUpInside];
NSLog(#"Row: %d, Poäng: %#", indexPath.row, btn_title);
label = (UILabel *)[cell viewWithTag:103];
label.text = btn_title;
button = (UIButton *)[cell viewWithTag:105];
[button setTag:2];
btn_title = [NSString stringWithFormat:#"%#", [row objectAtIndex:5]];
[button setTitle:btn_title forState:(UIControlState)UIControlStateNormal];
[button addTarget:self action:#selector(poangButtonClick:event:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
The first time button = (UIButton *)[cell viewWithTag:104]; is called on every visible row, everything is correct, but if I scroll or reload the view, button is nil?
Why? Retrieving a label the same way works, and is displayed correctly.
How can I change the label of the buttons in the cell?
Regards
/Fredrik
A quick guess: I see you are resetting the buttons "tag" value which you use to refere to it. So you cant retrive it (after changing it) anymore with the value 104 (after the first creation it is now 1 and 2)
[button setTag:1];
so, you wont get it the next time via
button = (UIButton *)[cell viewWithTag:105];
My assumption is that that the cell does not get deallocated and thus this tag value stays. Maybe this will solve it.