Reputation: 517
I use storyboard and Auto Layout. I add UISwitch to my cell with tag 5. When I choose first UISwitch and scroll down I see that other UISwitch is also turned on and if I scroll up my first UISwitch is turned off. How to fix this?
My code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UISwitch* switchView = (UISwitch *)[cell viewWithTag:5];
[switchView addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
return cell;
}
Upvotes: 2
Views: 2170
Reputation: 416
Try This:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"CellSetting";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [self.settingsArray objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if ([[self.settingsArray objectAtIndex:indexPath.row] isEqualToString:ROW_PRIVATE_BROWSING])
{
self.privateBrowsingSwitch =[[UISwitch alloc]initWithFrame:CGRectMake(cell.frame.size.width-65, 10, 30, 30)];
if (ApplicationDelegate.privateBrowsing)
{
[self.privateBrowsingSwitch setOn:YES animated:YES];
}
[self.privateBrowsingSwitch addTarget:self action:@selector(changeSwitch:) forControlEvents:UIControlEventValueChanged];
[cell addSubview:self.privateBrowsingSwitch];
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
Upvotes: 3
Reputation: 2674
Every time cellForRowAtIndexPath is called you have to replace the specific data that needs to be displayed for a cell at that position. This includes things like labels, images and your UISwitch.
This occurs because UITableViews use a small number of cells that are reused.
In cellForRowAtIndexPath add something like this:
switchView.on = [self isSwitchOnForCellAtIndexPath:indexPath]
Then write whatever logic is required to determine if the switch should be on or not.
Upvotes: 0
Reputation: 14487
This is because UITableView
reuse UITableViewCell
so one cell can be use more than once in different indexPaths, in this situation its your responsibility to maintain the state of UITableViewCell
subViews. Better place to do this is cellForRowAtIndexPath
where you are returning cell add logic to make show/hide UISwitch
or to select accurate state i.e. on or off, you can keep that flag in dataSource object and then you can check for that flag to make set right state for UISwitch
Upvotes: 3