自定义 UITableViewCell 背景,何时重新加载等

Posted

技术标签:

【中文标题】自定义 UITableViewCell 背景,何时重新加载等【英文标题】:Custom UITableViewCell backgrounds, when to reload, etc 【发布时间】:2012-04-19 00:25:05 【问题描述】:

我使用 cellForRowAtIndexPath 中的以下代码设置了自定义分组表视图样式。每个单元格都有一个新的背景视图,并且它的角根据其在该部分中的位置进行了圆角处理。我在整个应用程序中使用这种风格,在各种视图中我使用动画来添加和删除行。 (使用 [tableview insertRowsAtIndexPaths:] 等)。

如果插入或删除部分的最后一行,我需要能够重新加载单元格背景视图角。我怎样才能做到这一点而不调用 [tableview reloadData] 甚至 reloadCellsAtIndexPaths?这两个函数都会弄乱插入和删除单元格的动画。有没有什么地方可以放置这个在适当的时间被调用的背景角定义?默认的分组表视图是如何做到的?

抱歉,如果不清楚。要求澄清,我会编辑。谢谢! :)

UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) 
        cell = [[[UITableViewCell alloc] initWithStyle:[self styleForCellAtIndexPath:indexPath] 
                                       reuseIdentifier:cellIdentifier] autorelease];

        // Theme the cell
            TableCellBackgroundView *backgroundView = [[TableCellBackgroundView alloc] initWithFrame:cell.frame];
            TableCellBackgroundView *selectedBackgroundView = [[TableCellBackgroundView alloc] initWithFrame:cell.frame];
            selectedBackgroundView.selectedStyle = YES;
            // top row, without header
            BOOL header = [self tableView:aTableView heightForHeaderInSection:indexPath.section]!=0;
            if (indexPath.row == 0 && (!header || tableTheme==kTableThemeSimple)) 
                backgroundView.topRadius = 6;
                selectedBackgroundView.topRadius = 6;
            
            // bottom row
            if (indexPath.row == [self tableView:aTableView numberOfRowsInSection:indexPath.section]-1) 
                backgroundView.bottomRadius = 6;
                selectedBackgroundView.bottomRadius = 6;
            
            cell.backgroundView = backgroundView;
            cell.selectedBackgroundView = selectedBackgroundView;
            cell.contentView.backgroundColor = [UIColor clearColor];
            cell.backgroundColor = [UIColor clearColor];
        
    

【问题讨论】:

是否有一种干净的方法可以在单元格 layoutSubviews 或 drawRect 中检测应该绘制哪些角?我不介意子类化 UITableViewCell,我只是想不出有什么帮助.. 【参考方案1】:

如果你有一个调用自定义动画的方法,当动画完成时,或者在显示新单元格之前,使用 UITableViewCell 的子类调用一个名为 - (void ) fixCornersWithIndexPath: (NSIndexPath *) indexPath.

- (void) customAnimationForCellAtIndexPath: (NSIndexPath *) path 
    //your animation things
    CustomCell *cell = [self.tableView cellForRowAtIndexPath: indexPath];
    [cell fixCornersWithIndexPath: path andRowCount: [self tableView:aTableView numberOfRowsInSection:indexPath.section]];

然后修复角落应该是这样的:

- (void) fixCornersWithIndexPath: (NSIndexPath *) indexPath andRowCount: (NSInteger *) rowCount 
      if (indexPath.row == 0 && (!header || tableTheme==kTableThemeSimple)) 
            self.backgroundView.topRadius = 6;
            self.selectedBackgroundView.topRadius = 6;
        
        // bottom row
        if (indexPath.row == rowCount-1) 
            self.backgroundView.bottomRadius = 6;
            self.selectedBackgroundView.bottomRadius = 6;
        

希望这会有所帮助!

【讨论】:

【参考方案2】:

我想这就是你要找的。更改模型后,调用:

- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

这将导致调用您的 cellAtIndexPath 方法。发送一个包含过期行的单个索引路径的数组(我猜对于圆角问题,这是删除一行后的最后一行,或者是新添加的最后一行之前的行)。

您可以在开始/结束更新之间与其他更新方法一起调用它。

【讨论】:

【参考方案3】:

对我有用的解决方案是:

    在tableView中设置背景:willDisplayCell:forRowAtIndexPath: 创建一个名为 reloadBackgroundForRowAtIndexPath 的便捷方法,该方法手动调用 willDisplayCell

    当我添加一行时,延迟后调用便捷方法以使表格动画完成

    - (void)reloadBackgroundForRowAtIndexPath:(NSIndexPath*)indexPathToReload 
        [self tableView:self.tableView willDisplayCell:[self.tableView cellForRowAtIndexPath:indexPathToReload] forRowAtIndexPath:indexPathToReload];
    
    
    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
        // Logic to determine the background image
    
    
    // elsewhere, update the table, then
    NSIndexPath *indexPathToFix = [NSIndexPath indexPathForRow:count-1 inSection:0];
    // If the new row is coming out, we want to update the background right away.  If the new row is going away, we want to wait to update until the animation is done.
    // I don't like hard-coding the animation length here, but I don't think I have a choice.
    [self performSelector:@selector(reloadBackgroundForRowAtIndexPath:)  withObject:indexPathToFix afterDelay:(self.tableView.isEditing ? 0.0 : 0.2)];
    

【讨论】:

以上是关于自定义 UITableViewCell 背景,何时重新加载等的主要内容,如果未能解决你的问题,请参考以下文章

请问如何自定义UITableViewCell的背景颜色

何时何地根据实际宽度更新 UITableViewCell 子视图的约束

uitableviewcell 自定义背景问题

具有错误背景颜色的自定义 UITableViewCell

tvOS 上 UITableViewCell 的自定义背景

ios自定义UITableviewCell选择的背景颜色没有SelectedBackgroundView