I have a UITableview with "lessons" data fetch from a backend. The user can accept or refuse lessons with 2 uibuttons on the cell.
The problem is if the user refuse multiple lessons, the button seems to not be updated and refuse the wrong lesson.
Here is how I add my uibutton:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"userWaitingCell" forIndexPath:indexPath];
UIButton *acceptBtn = (UIButton *)[cell viewWithTag:200];
acceptBtn.tag = [[dic objectForKey:@"id"] integerValue] + 10000;
[acceptBtn addTarget:self action:@selector(acceptLesson:) forControlEvents:UIControlEventTouchUpInside];
UIButton *refuseBtn = (UIButton *)[cell viewWithTag:201];
refuseBtn.tag = [[dic objectForKey:@"id"] integerValue] + 10000;
[refuseBtn addTarget:self action:@selector(refuseLesson:) forControlEvents:UIControlEventTouchUpInside];
NSLog(@"Btn TAG: %ld", (long)refuseBtn.tag);
return cell;
I set the tag with the unique ID of the lesson from the backend database.
Here is how I handle the user tapping on a button:
- (void)refuseLesson:(id)sender
{
UIButton *senderBtn = (UIButton *)sender;
NSString *tmpUrl = [NSString stringWithFormat:@"%@%ld",
@"lesson/refuse/", senderBtn.tag - 10000];
NSLog(@"tmpUrL : %@", tmpUrl);
[dbService sendPostRequest:tmpUrl];
}
Here I can see in the NSLog that it's the wrong lesson ID.
When I finish the request I'm setting my data array like this:
for (int i = 0; i < [lessonList count]; i++)
{
NSMutableDictionary *lesson = [lessonList objectAtIndex:i];
if ([[lesson objectForKey:@"id"] integerValue] == [[dataDic objectForKey:@"id"] integerValue])
{
if ([[dataDic objectForKey:@"invitationStatus"] isEqualToString:@"accepted"])
{
[lesson setObject:@"accepted" forKey:@"invitationStatus"];
[lesson setObject:[dataDic objectForKey:@"lesson_count"] forKey:@"lesson_count"];
[lesson setObject:[dataDic objectForKey:@"lesson_done"] forKey:@"lesson_done"];
}
else if ([[dataDic objectForKey:@"invitationStatus"] isEqualToString:@"refused"])
{
[lesson setObject:@"refused" forKey:@"invitationStatus"];
[lessonList removeObjectAtIndex:i];
}
[self.myTableView reloadData];
NSLog(@"RELOADING");
return ;
}
}
Seems you are fetching your buttons by a tag you set up in story board: 200 and 201.
In your code, you then change the tag of the buttons to new values:
`[[dic objectForKey:@"id"] integerValue] + 10000`
At this point you have now changed the tags in the cell for those buttons.
On the next [self myTableView reloadData];
call, cells will be reused rather than created. None of these cells will have a view with a valid tag of 200 or 201.
What the buttons will have is the original action you added first time round.
Quickest Solution:
1) CTLR drag in IB your button into the cell header and create an IBOutlet for each button: acceptButton
and cancelButton
say. This allows your code to be able to reference the buttons directly in code. Do not use the tags 200 and 201 as they are nolonger needed.
2) In your cell create code, remove the fetch by tag 200 and 201 and simply reference them directly. Something like:
UIButton *acceptBtn = cell.acceptButton;
acceptBtn.tag = [[dic objectForKey:@"id"] integerValue] + 10000;
UIButton *refuseBtn = cell.refuseButton;
refuseBtn.tag = [[dic objectForKey:@"id"] integerValue] + 10000;
NSLog(@"Btn TAG: %ld", (long)refuseBtn.tag);
return cell;
3) CTRL - Drag your button prototype into your table view header and add an IBAction for each button. So use same code you have now for the actions.
This will stop the clash of the tags happening which I am pretty sure is your issue.