【问题标题】:Changing accessoryType for a row in a sectioned tableView after user selects the row在用户选择行后更改分段 tableView 中一行的附件类型
【发布时间】:2011-11-14 16:36:10
【问题描述】:

我有一个分段的 tableView,我希望我的用户从表中选择一个项目。当他们选择项目时,项目旁边应该会出现一个检查(使用UITableViewCellAccessoryCheckmark)。如果他们做出了先前的选择,则应从先前选择的行中删除检查。这是我正在使用的代码:

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

    int newRow = [indexPath row];

    int oldRow = [lastIndexPath row];

    if (newRow != oldRow || newRow == 0)
    {

        UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
        newCell.accessoryType = UITableViewCellAccessoryCheckmark;

        UITableViewCell *oldCell = [tableView cellForRowAtIndexPath: lastIndexPath]; 
        oldCell.accessoryType = UITableViewCellAccessoryNone;

        [lastIndexPath release];
        lastIndexPath = indexPath;  
    }

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

}

lastIndexPath.h 文件中私下声明。

此代码适用于未分段的小列表。但是在一个被分割的大表中,它会在其他部分的行中放置随机复选标记。几乎就像cellForRowAtIndexPath 忽略了 indexPath 中的部分。

如果我选择的行数大于最小部分中的行数,代码也会崩溃。

这是 cellForRowAtIndexPath 的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger section = [indexPath section];

    NSUInteger row = [indexPath row];

    NSString *key = [keys objectAtIndex:section];

    NSArray *itemSection = [items objectForKey:key];

    static NSString *SectionsTableIdentifier = @"SectionsTableIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:SectionsTableIdentifier] autorelease];

    }
    NSArray *rowLabel = [itemSection objectAtIndex:row]; 

    cell.textLabel.text = [rowLabel objectAtIndex:1];

    NSString *detText = [rowLabel objectAtIndex:0];

    detText = [detText stringByAppendingString:@"            $"];

    detText = [detText stringByAppendingString:[rowLabel objectAtIndex:2]];

    cell.detailTextLabel.text = detText;

    return cell;
}

【问题讨论】:

  • 需要查看cellForRowAtIndexPath: 的代码。我假设您正在使单元格出列并使用重用标识符(cellForRowAtIndexPath: 的默认实现)。如果是这种情况,那么您用于创建单元格的代码将重用带有复选标记的单元格作为模板来创建新单元格。为了解决这个问题,您可以做一些事情:“每次在cellForRowAtIndexPath: 中创建一个新单元格”或“保留对每个单元格的引用并绕过对cellForRowAtIndexPath: 的调用”
  • 是的 - 我明白你在说什么,这可以解决随机复选标记的第一个问题,但我认为如果我选择的行大于最小部分的行数。这是 cellForRowAtIndexPath 代码:
  • 您将无法将该代码发布到评论中。将其添加到您的原始帖子中

标签: iphone objective-c ios uitableview


【解决方案1】:

您在这里遇到的一个问题是如何将 indexPath 保存在 lastIndexPath 中。您需要保留您保存在 lastIndexPath 中的 indexPath。传递给这个方法的 indexPath 是自动释放的,所以如果你不保留它,它很可能会从你下面释放出来。这可能会导致您的崩溃。

【讨论】:

    【解决方案2】:

    这可能正是您正在寻找的。我为我的一个应用程序开发了这个。享受 ! (如果是,请标记为已回答) 另请注意,我使用的是 ARC,因此没有保留和释放。

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
       /* 
        1. First we get the indexPath from the prior priorSelectedRowInteger and priorSelectedSectionInteger ivars. Note: we could use a single indexPath ivar, but we separate them into row and section here for clarity.
        2. Then we reset the selectedRowInteger ivar to the currently selected row. This must be done before any rows are reloaded.
        3. Then we reload only the two rows at the concerned index paths, as we have captured the indexPath of the prior selected row and the method gives us the new one.  We could just simply reload the table here with [self.tableView reloadData], but it would not be animated and not as smooth.
    
        */
        NSIndexPath *priorSelectedIndexPath = [NSIndexPath indexPathForRow:priorSelectedRowInteger inSection: priorSelectedSectionInteger];
         // Now that we have the priorSelectedIndexPath, we save the new one for the next round.
         self.priorSelectedRowInteger = indexPath.row; 
         self.priorSelectedSectionInteger = indexPath.section;
    
        // For a changing tableView, check to make sure the priorIndexPath is still valid before trying to reload the prior row.
       // NSLog(@"priorSelectedIndexPath %@", priorSelectedIndexPath);
         if ((tableView.numberOfSections >= priorSelectedIndexPath.section+1) && ([tableView numberOfRowsInSection:priorSelectedIndexPath.section] >= priorSelectedIndexPath.row+1)) {
        NSArray *thePriorIndexPathArray = [NSArray arrayWithObject:priorSelectedIndexPath];
       [self.tableView reloadRowsAtIndexPaths:thePriorIndexPathArray withRowAnimation:UITableViewRowAnimationFade];
    }
    
    
        // Reload only the selected indexPath - necessary to update the text colors etc.
        NSArray *theIndexPathArray = [NSArray arrayWithObject:indexPath];
        [self.tableView reloadRowsAtIndexPaths:theIndexPathArray withRowAnimation:UITableViewRowAnimationFade];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-11
      • 2021-04-20
      相关资源
      最近更新 更多