0

我一直在遵循这个问题中的步骤: How to add a checkbox to a UITableView on the left, while using UITableViewCell caching?

我不想要一个简单的复选框来检查是否点击了一行,我需要一个仅在点击复选框时才会更改的复选框,因为单元格本身已经加载了所选项目的详细视图。

  • 如何将单元格“移动”到右侧,以便能够正确看到选中的按钮?(解决了这个问题:在 Storyboard 中,选择单元格,转到 Attributes Inspector,然后更改标识的宽度)

  • 我应该为标签使用什么,因为indexPath.row不起作用?如果我选择第一个项目,它会检查第 8 个(在所选答案中解决了这个)

更新:即使我选择了正确的答案,它也只能部分解决我的问题。重新加载视图时,选中的项目将移动到该部分的末尾,而不是保持与之前相同的顺序。有谁知道为什么?

这种情况的画面

这是 cellForRowAtIndexPath 的更新代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView2 dequeueReusableCellWithIdentifier:@"Cell2"];
UIButton *checkBox;
if (cell.tag == 0) {
    checkBox = [[UIButton alloc]initWithFrame:CGRectMake(5, 10, 20, 20)];
    UIImage *normalImage = [UIImage imageNamed: @"unchecked.png"];
    UIImage *selectedImage = [UIImage imageNamed: @"checked.png"];
    [checkBox setImage:normalImage forState:UIControlStateNormal];
    [checkBox setImage:selectedImage forState:UIControlStateSelected];
    [checkBox addTarget:self action:@selector(makeWatched:) forControlEvents:UIControlEventTouchUpInside];
    [cell.contentView addSubview:checkBox];
    cell.tag = 1;
}

for (id obj in cell.contentView.subviews) {
    if ([obj isKindOfClass:[UIButton class]]) {
        checkBox = obj;
        checkBox.tag = indexPath.row;
        break;
    }
}


Episodi *epi = [self.fetchedResultsController objectAtIndexPath:indexPath];


 checkBox.selected = ([self.selectedChecks containsObject:[NSNumber numberWithInt:  (indexPath.row)]])? YES : NO;

if ([epi.watched isEqualToString:@"1"]) {

    NSLog(@"Entra");
    checkBox.selected = YES;

}

cell.textLabel.text = epi.episodeTitle;
return cell;

}

更新复选框操作的代码:

-(void)makeWatched:(UIButton *) checkButton {
    if (checkButton.selected == NO) {

       Episodi *epi = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:checkButton.tag inSection:sectionNumber]];
       [epi setWatched:@"1"];
       checkButton.selected=YES;
       NSError *error = nil;
       if (![managedObjectContext save:&error]) {
           NSLog(@"Saving changes failed: %@", error);
       } else {
        // The changes have been persisted.
    }

    [self.selectedChecks addObject:[NSNumber numberWithInt:(checkButton.tag)]];


    [self.tableView2 reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:checkButton.tag inSection:sectionNumber]] withRowAnimation:UITableViewRowAnimationNone];



}else{

    Episodi *epi = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:checkButton.tag inSection:sectionNumber]];
    [epi setWatched:@"0"];
    if ([epi.watched isEqualToString:@"0"]){
       NSLog(@"Not Watched anymore");
    }
    checkButton.selected=NO;
    NSError *error = nil;
    if (![managedObjectContext save:&error]) {
        NSLog(@"Saving changes failed: %@", error);
    } else {
        // The changes have been persisted.
    }


    [self.selectedChecks removeObjectIdenticalTo:[NSNumber numberWithInt:(checkButton.tag)]];
    [self.tableView2 reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:checkButton.tag inSection:sectionNumber]] withRowAnimation:UITableViewRowAnimationNone];
  }
 }
4

2 回答 2

2

您应该创建一个 UITableViewCell 的子类并使用 xib 来布局自定义单元格中的复选框和标签。在tableView:cellForRowAtIndexPath:. 这样,您的自定义复选框将被缓存,而不是每次都重新创建。您仍然需要设置复选框的值(选中或未选中)tableView:cellForRowAtIndexPath:

查看本教程以了解如何使用 xib 创建自定义 UITableViewCell:http: //iosmadesimple.blogspot.sg/2012/10/uitableviewcell-using-interface-builder.html

于 2013-05-17T14:44:12.213 回答
2

您做错的一件事是在单元格中添加了多个复选框。如果单元格不为零,则输入“else”子句——该单元格已经有一个带有其标签的复选框。然后,您使用自己的标签向该单元格添加另一个复选框。

您应该重构代码以仅在单元格为零时添加任何子视图。任何与内容有关的事情,包括复选框的标签,都应该在 if 子句之外完成。

编辑后:

这是一种方法。我将复选框的创建包装在 if 语句中,以便只将一个复选框添加到单元格(新创建的单元格将具有默认标记值 0)。我有一个数组 selectedChecks,它包含所有选中框的行(请记住在 viewDidLoad 中创建该数组)。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    UIButton *checkBox;
    if (cell.tag == 0) {
        checkBox = [[UIButton alloc]initWithFrame:CGRectMake(-5, 10, 20, 20)];
        UIImage *normalImage = [UIImage imageNamed: @"Uncheck.png"];
        UIImage *selectedImage = [UIImage imageNamed: @"Check.png"];
        [checkBox setImage:normalImage forState:UIControlStateNormal];
        [checkBox setImage:selectedImage forState:UIControlStateSelected];
        [checkBox addTarget:self action:@selector(makeWatched:) forControlEvents:UIControlEventTouchUpInside];
        [cell.contentView addSubview:checkBox];
        cell.tag = 1;
    }

    for (id obj in cell.contentView.subviews) {
        if ([obj isKindOfClass:[UIButton class]]) {
            checkBox = obj;
            checkBox.tag = indexPath.row;
            break;
        }
    }
    checkBox.selected = ([self.selectedChecks containsObject:@(indexPath.row)])? YES : NO;
    cell.textLabel.text =  self.theData[indexPath.row];       
    return cell;
}


-(void)makeWatched:(UIButton *) checkButton {
    if (checkButton.selected == NO) {
        [self.selectedChecks addObject:@(checkButton.tag)];
        [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:checkButton.tag inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
    }else{
        [self.selectedChecks removeObjectIdenticalTo:@(checkButton.tag)];
        [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:checkButton.tag inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
    }
}

这应该可以,但我认为为您的单元格创建一个自定义类并在情节提要中添加按钮,并在您的自定义单元格 .h 文件中为该按钮添加一个 IBOutlet 会更容易。

于 2013-05-17T15:08:40.607 回答