Travis Griggs
Travis Griggs

Reputation: 22252

How to do (custom) selection with custom UITableViewCell subclass

I have a UITableView with a custom UITableCellView subclass. I want to show one of the rows as active or selected. The controls in my cell have their own gestures, but I have area on the right where I can do the selection. I had (naively) thought I could just indicate I wanted a checkmark style accessory but Apple's docs say

This control does not track touches. The delegate of the table view can manage check marks in a section of rows (possibly limiting the check mark to one row of the section) in its tableView:didSelectRowAtIndexPath: method.

I'm not sure how to interpret that, but I put the tableView:didSelectRowAtIndexPath: method in my delegate, and it never fires. Regardless of where I touch my cell (on the part where there are touchable controls or not). So I'm curious why that doesn't work? I also noticed that regardless of how I set the selected property on the cells, the checkmark always shows on, so I don't think it's really meant to be used a selection indicator.

But I'm actually kind of OK with that. I don't really want a checkmark, I'd rather do something like mail does when it does multi select on the left side, the radio-button-esque style circles. Which then leads me to a quandary about how to proceed. Should I just add a button control to the right side, manipulate the images appropriately in my custom cell subclass? Do I mess with the background image of the button in that case? Or just the image? And since selecting one needs to deselect the others, what's the best way to connect this to the table view delegate, rather than the subclass? Or should I make a custom NSView subclass?

UPDATE

I removed the accessory. I added an UIImageView to show selection state. Because the sub control in my cell uses a hold gesture, the selection tap makes it through just about everywhere for the cell. I synchronize the visual selection state using the following method:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    self.selectionView.image = self.selected ? [UIImage imageNamed: @"selected"] : [UIImage imageNamed: @"not_selected"];
}

To my custom controller, I added the following method:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [Site setCurrent: self.allSites[indexPath.row]];
    [[Site current] pullValves];
}

It finally donned on me that that the first method was for updating the visual state, but not for responding to the users intent, that belongs in the second method. The first fires at various times, but the second applies when the user actually does the tap.

Finally, I had to programmatically set

self.clearsSelectionOnViewWillAppear= NO;

Not matter what I set in the storyboard, that value was YES, so returning to the list was clearing my selection.

Upvotes: 0

Views: 572

Answers (1)

David McGraw
David McGraw

Reputation: 5177

You're adding a gesture to each of the cells you create? I would back that out of there and create a gesture on the main controller which holds your tableview (not the individual cells).

Add this to your main controller so the controller can handle the gestures accordingly.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

If you need to track the cell that was touched (say, for a panning gesture), you can grab the index path given the gesture recognizer.

CGPoint p = [recognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];

From there, we go back to your goal: tracking your active cell. tableView:didSelectRowAtIndexPath needs to be hit (hopefully the steps above help here). Store some sort of identifier of the item you need to keep selected. When tableView:willDisplayCell:forRowAtIndexPath is called you can trigger the selection state.

Upvotes: 1

Related Questions