点击单元格时,在UITableViewCell上放置复选标记

时间:2015-03-01 10:08:32

标签: ios objective-c uitableview

点击单元格时,我想在UITableViewCell上添加复选标记。

但是当点击一个单元格并滚动tableView时,其他单元格也会显示复选标记。

(我认为这是因为UITableViewCell被重复使用。)

我有这段代码。

ViewController.m

@property (nonatomic, strong) NSMutableArray* selectedItems;

- (void)viewDidLoad
{
    NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
    self.selectedItems = [NSMutableArray array];
    if ([ud objectForKey:@"SelectedItems"] != nil) {
        self.selectedItems = [ud objectForKey:@"SelectedItems"];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString* cellIdentifier = @"Cell";
    CustomCell* cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    if (cell.isChecked == YES) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }else if (cell.isChecked == NO) {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }    
    return cell;
}

//when tapping the cell, put a check mark
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell* cell = (CustomCell *)[tableView cellForRowAtIndexPath:indexPath];
    cell.isChecked = YES;
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    [self.selectedItems addObject:cell.titleLabel.text];
    NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
    [ud setObject:self.selectedItems forKey:@"SelectedItems"];
    [ud synchronize];
}

CustomCell.h

@property BOOL isChecked;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;


我只想在选定的单元格上打勾 我该如何解决?

4 个答案:

答案 0 :(得分:2)

问题是您将已检查/未检查的信息存储在您的单元格中,即视图而不是数据源,因此违反了MVC的基本原则(模型 - 视图 - 控制器)范例。

相反,在您的cellForRowAtIndexPath中,您必须检查存储在用户默认值中的数据,然后决定是否应该检查该单元格。

此外,假设您在类中有一个实例变量,而不是访问每个单元格的用户默认值,而是在视图加载时从用户默认值中读取。假设您的数据源具有此结构(字典数组):

@[@"text" : @"firstCellText",  @"checked" : @NO},
  @"text" : @"secondCellText", @"checked" : @YES}]

你当然可以用各种不同的方式做到这一点,所以上面只是为了说明。

// cellForRowAtIndexPath
cell.accessoryType = 
 [datasource[indexPath.row][@"checked"] boolValue] ?
 UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;

答案 1 :(得分:0)

您应该保留一个变量,告诉您已经点击了该单元格,并在didSelectRow中不断检查其状态。

检查:Issue while reusing table view cell?

答案 2 :(得分:0)

由于单元格是可重复使用的,因此" isChecked"您正在使用的属性也与单元格保持完整,因此要检查您必须跟踪“索引路径”的单元格的选择。细胞的性质。

声明属性lastIndexPath以跟踪抽头单元格

@property NSIndexPath* lastIndexPath;


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

    // Configure the cell...


    if ([indexPath compare:self.lastIndexPath] == NSOrderedSame)
    {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else
    {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath   *)indexPath
{
   [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
    self.lastIndexPath = indexPath;

    [self.selectedItems addObject:cell.titleLabel.text];
    NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
    [ud setObject:self.selectedItems forKey:@"SelectedItems"];
    [ud synchronize];

}

答案 3 :(得分:0)

删除/评论if (cell == nil) {&你做完了..

这种情况正在发生,因为正在重复使用细胞。