Iphone:UITableview中的选中标记在滚动时会混淆

时间:2011-08-04 18:53:55

标签: iphone objective-c ios xcode

我有一个问题,我在UITableView中应用于我的行的复选标记在滚动时会混淆。我很确定这与iphone如何重复使用单元格有关,当我向上滚动时有一个复选标记,它可能会在我有机会时将其重新放入。

有人可以给我一些提示,告诉我如何避免这种情况,或者可能会看一下我的方法,看看有什么看不见的东西吗?

我在想,也许我可以保存用户所做的每一行选择,然后检查哪些行正在显示,以确保正确的行得到了复选标记,但我看不到这样做的方法。< / p>

非常感谢。

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

static NSString *CellIdentifier = @"Cell";

CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    [cell setAccessoryView:nil];
}

NSMutableArray *temp = [[NSMutableArray alloc]init];
for (int j = 0; j < [listOfRowersAtPractice count]; j++) {
    if ([[differentTeams objectAtIndex:indexPath.section] isEqualToString:[[rowersAndInfo objectForKey:[listOfRowersAtPractice objectAtIndex:j]]objectForKey:@"Team"]]) {
        [temp addObject:[listOfRowersAtPractice objectAtIndex:j]];
    }
}

[cell.cellText setText:[temp objectAtIndex:indexPath.row]]; 

[temp removeAllObjects];
[temp release];
// Set up the cell...


return cell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


        [tableView deselectRowAtIndexPath:indexPath animated:YES];

        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        if (cell.accessoryType != UITableViewCellAccessoryCheckmark) {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }else {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
    }

5 个答案:

答案 0 :(得分:1)

是保存所选行的状态,并在单元格将其重置为默认状态并检查行状态并更改状态后保存在cellforrowatindexpath中。

编辑:

您可以创建一个NSMutabaleArray,其项目数等于数据源中的项目数,即代码中的名称temp。

在选择时,您实际上可以将该索引处的值更改为某些文本,例如上面创建的数组中的@“selected”。

在您的cellforrowatindex路径中,您可以检查此文本是否已选中或未选中,然后更改单元格的属性。它就像为选定和未选择状态维护位图状态一样。

答案 1 :(得分:0)

每次重复使用单元格时,都需要重置/清除单元格中的所有设置。 所以,在你拿到牢房之后,

你需要做类似

的事情
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    [cell setAccessoryView:nil];
}

cell.accessoryType = UITableViewCellAccessoryNone // This and other such calls to clean up the cell

答案 2 :(得分:0)

放手一搏:

static  NSString *CellIdentifier = [NSString stringWithFormat:@"Cell %d",indexPath.row];

我在其中一个应用上遇到了同样的问题。

对于复选标记,您是否正在使用核心数据存储?

如果您使用以下内容....

   - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *item = [[self fetchedResultsController] objectAtIndexPath:indexPath];

if ([[item valueForKey:@"checks"] boolValue]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        [cell.textLabel setTextColor:[UIColor redColor]];
        [cell.detailTextLabel setTextColor:[UIColor redColor]];


} else {
    cell.accessoryType = UITableViewCellAccessoryNone;
    [cell.textLabel setTextColor:[UIColor blackColor]];
    [cell.detailTextLabel setTextColor:[UIColor blackColor]];
}


}

和......

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *selectedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];



if ([[selectedObject valueForKey:@"checks"] boolValue]) {
    [selectedObject setValue:[NSNumber numberWithBool:NO] forKey:@"checks"];
} else {
    [selectedObject setValue:[NSNumber numberWithBool:YES] forKey:@"checks"];
}

[managedObjectContext save:nil];

}

答案 3 :(得分:0)

您需要刷新单元格的accessoryType,因为单元格被重用,然后它从重用的单元格继承了accessoryType,这就是解决方案:

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

    //Refresh acessory for cell when tableview have many cells and reuse identifier
    if([self.tableView.indexPathsForSelectedRows containsObject:indexPath]){
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }else{
       cell.accessoryType = UITableViewCellAccessoryNone;
    }

    cell.textLabel.text = @"Your text cell";

    return cell;
}

答案 4 :(得分:0)

它对我有用.. 在索引路径的行的单元格中,我创建了一个复选框按钮。 在everytym tableview滚动后,调用cellForRowAtIndexPath方法 因此我必须在cellForRowAtIndexPath中添加条件以检查单元格是否具有选中或未选中的按钮

static NSString *simpleTableIdentifier = @"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) 
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"SimpleTableCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];
} 

cell.nameLabel.text = [tableData objectAtIndex:indexPath.row];
cell.thumbnailImageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]];
cell.prepTimeLabel.text = [prepTime objectAtIndex:indexPath.row];
checkbox = [[UIButton alloc]initWithFrame:CGRectMake(290, 5, 20, 20)];
[checkbox setBackgroundImage:[UIImage imageNamed:@"checkbox_empty.png"]
                                forState:UIControlStateNormal];

[checkbox addTarget:self action:@selector(checkUncheck:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:checkbox];
if(selectedRows.count !=0)
{
if([[selectedRows objectAtIndex:indexPath.row]integerValue]==1)
{
    [checkbox  setImage:[UIImage imageNamed: @"checkbox_full.png"] forState:UIControlStateNormal];
}
else
{
    [checkbox  setImage:[UIImage imageNamed: @"checkbox_empty.png"] forState:UIControlStateNormal];
}
}
return cell;
}

定义复选框选择的方法为

- (IBAction)checkUncheck:(id)sender {
UIButton *tappedButton = (UIButton*)sender;

NSLog(@"%d",tappedButton.tag);
if ([[sender superview] isKindOfClass:[UITableViewCell class]]) {
    UITableViewCell *containerCell = (UITableViewCell *)[sender superview];
    NSIndexPath *cellIndexPath = [self.tableView indexPathForCell:containerCell];
    int cellIndex = cellIndexPath.row;
    NSLog(@"cell index%d",cellIndex);
    [selectedRows insertObject:[NSNumber numberWithInt:1] atIndex:cellIndex];

}
NSLog(@"%@",selectedRows);
if([tappedButton.currentImage isEqual:[UIImage imageNamed:@"checkbox_empty.png"]])
{
    [sender  setImage:[UIImage imageNamed: @"checkbox_full.png"] forState:UIControlStateNormal];
}
else
{
    [sender  setImage:[UIImage imageNamed: @"checkbox_empty.png"] forState:UIControlStateNormal];

}
}

不要忘记初始化selectedRows数组.. 快乐的编码...... !!!