UISwitch in a custom accessoryView

2.4k views Asked by At


I have my UITableViewCell subclass in which I use an UISwitch as accessoryView in this way:
mySwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
self.accessoryView = mySwitch;
and all is ok! The app works fine.

Now I need to add some UIImageView above the switch, so I thought "Well, let's make a custom accessoryView!":
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 10.0f, 100.0f, 60.0f)];
...
mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0.0f, 22.0f, 94.0f, 27.0f)];
[myView addSubview:mySwitch];
self.accessoryView = myView;
[myView release];

All seems to be ok, but there is a strange behavior. When I open another viewcontroller and get back to the table the switches are mysteriously changed...
It's not a problem in data management, but only in the cell redraw... Please, help me, what can I do?

Thanks in advance

2

There are 2 answers

0
qfwfq On BEST ANSWER

Emh... I found the problem... it was not linked to table redraw...
On UIControlEventValueChanged the selector retrieves the switch value and the cell indexPath.row in this way:
UISwitch *tempSwitch = (UISwitch *)sender;
UITableViewCell *cell = (UITableViewCell *)[tempSwitch superview];

and then it updates the corresponding object (of a data logic class) saved in a NSMutableArray (the datasource of the tableview)

But now the switch is a not the accessoryView, but a subview of the accessoryView, so the object is updates in a unpredictable way. I solved with a second superview message.

Sorry for my mistake and thanks to all...

2
Max On

This happens because cells are reused. So if you added subview to cell's content view and then after that cell is reused in another row, that view will appear in that row. The best way to avoid this, is to hold NSArray in your table's datasource (it's usually your view controller) that contains all the custom views (with subviews). Then you can do like this:

-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath {
    NSInteger row = indexPath.row;
    static NSString* cellIdentifier = @"Trololo";

    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier];
    if( !cell ) {       
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier: cellIdentifier] autorelease];
    }

    [[cell.contentView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
    [cell.contentView addSubview: [_your_cell_views objectAtIndex: row]];

    return cell;
}