【问题标题】:Iphone: Checkmarks in UITableview get mixed up when scrollingIphone:滚动时 UITableview 中的复选标记会混淆
【发布时间】:2011-10-20 07:01:02
【问题描述】:

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

有人可以给我一些提示,告诉我如何避免这种情况,或者看看我的方法,看看有没有什么不对劲的地方?

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

非常感谢。

- (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;
        }
    }

【问题讨论】:

    标签: iphone objective-c ios xcode


    【解决方案1】:

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

    编辑:

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

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

    在您的 cellforrowatindexpath 中,您可以检查此文本是否选中或未选中,然后更改单元格的属性。这就像为选定和未选定状态维护一个位图状态。

    【讨论】:

    • 你能写出我如何将行放入数组中,如果它被选中,但如果它已经在数组中,则将其删除?
    【解决方案2】:

    每当您重复使用该单元格时,您都需要重置/清除该单元格中的所有设置。 所以在这里,就在你拿到细胞之后,

    你需要做类似的事情

    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
    

    【讨论】:

      【解决方案3】:

      试一试:

      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];
      
      }
      

      【讨论】:

      • 显然这是从我的一个项目中提取的,但我确定如果您不使用核心数据,您将能够轻松创建一个 .plist 来存储值。
      【解决方案4】:

      你需要刷新cell的accessoryType,因为cell被重用了,然后它从一个重用的Cell继承了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;
      }
      

      【讨论】:

        【解决方案5】:

        它对我有用.. 在索引路径的行单元格中,我创建了一个复选框按钮.. 在每个表视图滚动后 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 数组。 编码快乐...!!!

        【讨论】:

          猜你喜欢
          • 2013-01-04
          • 2015-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多