user3335395
user3335395

Reputation: 59

Creating a button for every UITableViewCell

I'm trying to create an friend request function. Where all the friend request would show up in a table and a player will get to click accept or decline. What I'm trying to do is create an accept button beside this UITableView that contains all the player's friend requests.

Here's my code.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *notificationCell = [tableView dequeuREusableCellWithIdentifier@"notificationCell" for IndexPath:indexPath];

    NSArray *friendRequests = [self fetchAllFriendRequestsInArray];
    NSManagedObject *friendRequestingRelationship = [friendRequests objectAtIndex:indexPath.row];
    notificationCell.textLabel.text = [friendRequestingRelationship valueForKey:@"name"];

    UIButton *acceptButton = [UiButton buttonWithType:UIButtonTypeSystem];

    [acceptButton.frame = CGRectMake(notificationCell.frame.origin.x + 150, notificationcell.frame.origin.y -20, 80, 40);
    [acceptButton setTitle:@"Accept" forState:UIControlStateNormal];
    acceptButton.backgroundColor = [UIColor clearColor];
    [acceptButton addTarget:self action:@selector(acceptButtonPressed) forControlEvents:UIControlEventTouchUpInside];

    [notificationCell.contentView addSubview:acceptButton];

    return notificationCell;
}

Only the first notificationCell showed the friendrequester's name and Accept Button. Other notificationCells only showed other friendrequesters' names without the button. May I know what is wrong with my code such that I can allow the button to be shown on every single cell?

Thank you in advance!

Upvotes: 0

Views: 249

Answers (2)

AdamG
AdamG

Reputation: 3718

This is a bad approach to solving this problem to begin with. You should go to the storyboard, and drop a button in a prototype cell. Then select that button, go to the attributes inspector, and set the "tag" to a number of your choice (for this example we will say 1). You can then get the button for each cell like so after grabbing the cell:

UIButton * acceptButton = (UIButton *)[cell viewWithTag: 1];
[acceptButton addTarget:self action:@selector(acceptButtonPressed) forControlEvents:UIControlEventTouchUpInside];

This is cleaner and will give you the results you want.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

The buttons are there, but they are clipped from the view. This line is the culprit:

acceptButton.frame = CGRectMake(notificationCell.frame.origin.x + 150, notificationcell.frame.origin.y -20, 80, 40);

You shouldn't add the origin of notificationCell to the button, because subview positions are relative to positions of their superviews.

This should give you the right look, but your code has other potential problems.

  • The line where you fetch all friend requests is probably too slow to be executed for each cell in the view. Make sure that the results are cached
  • Table view cells are recycled. When one of such recycled cells makes it to your code, it looks like your code adds a second button on top of the first one
  • Similarly, if a recycled cell with a button is returned for the cell that does not need a button, the old button would remain visible.

You may be better off using a prototype cell that already has a button on it. Instead of adding and removing that button, you could make the existing one visible or invisible, depending on the context.

Upvotes: 1

Related Questions