UITwitch在UITableView Bug中

时间:2014-04-29 10:04:49

标签: ios uitableview uiswitch

我的UITableViewCell原型中有一个UISwitch。

问题是,当我打开其中一个开关时,其中一个未显示的开关也会打开。

在显示所有单元格的iPad版本中不会发生这种情况。

以下是一些代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];

    Notification *notification = [notifications objectAtIndex:indexPath.row];

    UILabel *titleLabel = (UILabel *) [cell viewWithTag:100];
    UISwitch *newsSwitch = (UISwitch *) [cell viewWithTag:101];
    UIImageView *imageView = (UIImageView *) [cell viewWithTag:102];

    [titleLabel setText:[notification name]];
    [imageView setImage:[UIImage imageNamed:[notification image]]];

    BOOL isOn = [storage boolForKey:[NSString stringWithFormat:@"notification_%@", [notification name]]];
    [newsSwitch setOn:isOn];
    [newsSwitch setTag:indexPath.row];
    [newsSwitch addTarget:self action:@selector(didChangeStateForSwitch:) forControlEvents:UIControlEventValueChanged];

    return cell;
}

2 个答案:

答案 0 :(得分:1)

第一次加载单元格时,您正在使用带有标记101的视图进行切换。之后很少行为此开关设置新标记,下次当您尝试使用标记101进行查看时,它不会#39 ; t存在。[newsSwitch setTag:indexPath.row]; 删除此行并再试一次

您可以将索引路径设为@DarkDust建议

- (void)didChangeStateForSwitch:(id)sender
{
NSIndexPath *indexPath = [myTableView indexPathForCell:[sender superview]];
...
}

答案 1 :(得分:1)

您的问题是您首先通过其标记查询交换机:

UISwitch *newsSwitch = (UISwitch *) [cell viewWithTag:101];

但是稍后,你改变了那个标签:

[newsSwitch setTag:indexPath.row];

因此,当单元格被重用时,将找不到开关,因为现在它的标签不再是101。因此,开关将处于旧状态。

您可以在查询交换机后添加NSLog(@"Switch: %@", newsSwitch);来轻松验证这一点。您会看到它会为那些您有“错误”切换值的行输出Switch: (null)

解决方法是不修改标签。

问题是,你怎么记得开关用于哪一行呢?一种方法是:

- (void)didChangeStateForSwitch:(id)sender
{
    NSIndexPath *indexPath = [myTableView indexPathForCell:[sender superview]];
    ...
}

另一种可能性是使用associated objects