目标C - TableView复选框使用章节的问题

时间:2015-09-21 18:43:48

标签: ios objective-c uitableview

我正在使用以下代码在我的UITableView中实现联系人复选框功能。

我遇到的问题是,当检查几个用户然后向上/向下滚动表时,不应该被检查的用户显示为已选中,反之亦然。

我认为它与我的细胞创建中的错误有关,但我不太确定是什么。

- (void)viewDidLoad {

    ...

    self.checkedUsers = [[NSMutableArray alloc] init];

    for (int i=0; i<self.allContacts.count; i++) {
        [self.checkedUsers insertObject:@"FALSE" atIndex:i];
    }

    ...
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     static NSString *simpleTableIdentifier = @"SocietyContactCell";
     SocietyContactCell *cell = (SocietyContactCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

          if (cell == nil) {        
          NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"SocietyContactCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
          }

     BOOL checked =  [[self.checkedUsers objectAtIndex:indexPath.row] boolValue];
     UIImage *image = (checked) ? [UIImage imageNamed:@"checkedContact.png"] : [UIImage imageNamed:@"uncheckedContact.png"];

     [cell.checkButton setBackgroundImage:image forState:UIControlStateNormal];
     [cell.checkButton addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
}

- (void)buttonPressedAction:(id)sender
{
    UIButton *button = (UIButton *)sender;
    int row = button.tag;

    BOOL checked = [[self.checkedUsers objectAtIndex:row] boolValue];
    [self.checkedUsers removeObjectAtIndex:row];
    [self.checkedUsers insertObject:(checked) ? @"FALSE":@"TRUE" atIndex:row];

    UIImage *newImage = (checked) ? [UIImage imageNamed:@"uncheckedContact.png"] : [UIImage imageNamed:@"checkedContact.png"];
    [button setBackgroundImage:newImage forState:UIControlStateNormal];

}

编辑:我现在意识到这个问题很可能源于我在这个TableView中使用的部分。联系人按字母顺序排列,这会搞乱我的标签。

如何使用部分解决此问题?

3 个答案:

答案 0 :(得分:0)

此处的问题是保留单元格中的复选标记状态。由于表单元格在滚动时被重用,因此再次调用cellForRowAtIndexPath方法,并且不再在那里设置复选标记的值。

您必须创建一个全局数组,该数组将存储每个indexPath的复选标记的状态。然后,您可以在checked/unchecked方法中设置复选标记按钮cellForRowAtIndexPath的状态。

添加以下代码段以及代码show:

 [cell.checkButton addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
 [cell.checkButton setTag:indexPath.row];

另外,请替换这些行:

[self.checkedUsers removeObjectAtIndex:row];
[self.checkedUsers insertObject:(checked) ? @"FALSE":@"TRUE" atIndex:row];

用这个:

[self.checkedUsers replaceObjectAtIndex:row withObject:checked ? @"TRUE" : @"FALSE"];

答案 1 :(得分:0)

我不知道你每次在cellForRowAtIndexPath:中设置button.tag的位置,所以action方法可能会更新self.checkedUsers数组中的错误行,尽管action方法会独立更新单元格&#39 ;此刻正确的图像。然而,当您向上和向下滚动时,显示将返回到self.checkedUsers数组中的状态。

您可能需要一行:

cell.checkButton.tag = indexPath.row;
你的cellForRowAtIndexPath:方法中的

其次,你的action方法是在self.itsToDoChecked上获取状态,然后更新self.checkedUsers数组,当它出现时它应该作用于同一个数组(简单地反转给定行索引的状态)。不确定这只是一个示例代码错误或重要的事情。

编辑:也有可能在单元子类中有状态导致问题;很难确定。您希望在该类中实现-prepareForReuse(并始终调用super)以将任何状态重置为初始值。

答案 2 :(得分:0)

在您的SocietyContactCell类中添加以下方法:

- (void)prepareForReuse {
    [super prepareForReuse];
    [self.checkButton setBackgroundImage:nil forState:UIControlStateNormal];
}