Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
439 views
in Technique[技术] by (71.8m points)

iphone - UITableView, having problems changing accessory when selected

I'm using a UITableView to allow selection of one (of many) items. Similar to the UI when selecting a ringtone, I want the selected item to be checked, and the others not. I would like to have the cell selected when touched, then animated back to the normal color (again, like the ringtone selection UI).

A UIViewController subclass is my table's delegate and datasource (not UITableViewController, because I also have a toolbar in there).

I'm setting the accessoryType of the cells in cellForRowAtIndexPath:, and updating my model when cells are selected in didSelectRowAtIndexPath:. The only way I can think of to set the selected cell to checkmark (and clear the previous one) is to call [tableView reloadData] in didSelectRowAtIndexPath:. However, when I do this, the animating of the cell deselection is weird (a white box appears where the cell's label should be). If I don't call reloadData, of course, the accessoryType won't change, so the checkmarks won't appear.

I suppose I could turn the animation off, but that seems lame. I also toyed with getting and altering the cells in didSelectRowAtIndexPath:, but that's a big pain.

Any ideas? Abbreviated code follows...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell* aCell = [tableView dequeueReusableCellWithIdentifier:kImageCell];
    if( aCell == nil ) {
        aCell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:kImageCell];
    }

    aCell.text = [imageNames objectAtIndex:[indexPath row]];
    if( [indexPath row] == selectedImage ) {
        aCell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        aCell.accessoryType = UITableViewCellAccessoryNone;
    }
    return aCell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    selectedImage = [indexPath row]
    [tableView reloadData];
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I solved it like hatfinch suggested in his edit. My code sample make sure there's only one row checked but I'm sure you can tweak it if thats not what you need.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

int newRow = [indexPath row];
int oldRow = [lastIndexPath row];

if (newRow != oldRow)
{
    UITableViewCell *newCell = [tableView cellForRowAtIndexPath:
                                indexPath];
    newCell.accessoryType = UITableViewCellAccessoryCheckmark;

    UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:
                                lastIndexPath];
    oldCell.accessoryType = UITableViewCellAccessoryNone;

    lastIndexPath = indexPath;
}

[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...