Juan Andres
Juan Andres

Reputation: 433

Change detail disclosure indicator image on touch

Is it possible to change the UITableViewCellAccessoryDetailDisclosureButton image on touch?

I would like to have my rows in the tableView to have an empty circle in place of the detail disclosure button. When I tap this empty circle button, I would like to change the image of the empty circle with another image containing a checkmark. Then after a delay of about half a second I would like to perform an action with the -accessoryButtonTappedForRowWithIndexPath.

How can I do this?

Upvotes: 2

Views: 2215

Answers (2)

Ben M
Ben M

Reputation: 2475

Well first you'd have to set the accessoryView of your cell to be a custom UIView, probably a UIButton...

UIImage *uncheckedImage = [UIImage imageNamed:@"Unchecked.png"];
UIImage *checkedImage = [UIImage imageNamed:@"Checked.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(44.0, 44.0, image.size.width, image.size.height);
[button addTarget:self action:@selector(tapButton:) forControlEvents:UIControlEventTouchUpInside];
[button setImage:uncheckedImage forState:UIControlStateNormal];
[button setImage:checkedImage forState:UIControlStateSelected];
cell.accessoryView = button;

In your tapButton: method you want to apply the necessary changes to the image and perform the accessoryButtonTappedAtIndexPath. I would just avoid the delay or you could use a dispatch timer...

- (void)tapButton:(UIButton *)button {
  [button setSelected:!button.selected];
  UITableViewCell *cell = [button superview];
  NSIndexPath *indexPath = [tableView indexPathForCell:cell];
  [self tableView:tableView accessoryButtonTappedForRowWithIndexPath:indexPath];

}

Upvotes: 2

rob mayoff
rob mayoff

Reputation: 385690

According to your comment, you are already creating your own button and setting it as the cell's accessoryView.

When you create the button, set its image for the selected state to your checkmark image:

[button setImage:checkmarkImage forState:UIControlStateSelected];

When the button is tapped, set its state to selected so it will show the checkmark:

- (IBAction)buttonWasTapped:(id)sender event:(UIEvent *)event {
    UIButton *button = sender;
    button.selected = YES;

Then, disable user interactions so the user can't do anything else during the delay:

    [[UIApplication sharedApplication] beginIgnoringInteractionEvents];

Get the index path for the cell containing the touched button:

    UITouch *touch = [[event touchesForView:button] anyObject];
    NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:
        [touch locationInView:tableView]];

Finally, schedule a block to run after the delay. In the block, re-enable user interactions and send yourself a message including the index path:

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC),
        dispatch_get_main_queue(),
    ^{
        [[UIApplication sharedApplication] endIgnoringInteractionEvents];
        [self accessoryButtonTappedForRowAtIndexPath:indexPath];
    });
}

Upvotes: 1

Related Questions