WildWorld
WildWorld

Reputation: 517

UITableView with UISwitch

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

Answers (3)

Parth Bhadaja
Parth Bhadaja

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

Robert Wagstaff
Robert Wagstaff

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

Adnan Aftab
Adnan Aftab

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

Related Questions