UITableView的deselectRowAtIndexPath可防止单元格的子视图改变背景颜色

时间:2017-06-08 16:28:36

标签: ios uitableview

我正在使用自定义单元格进行tableview。我需要通过设置标题标签的背景颜色来突出显示当前所选(活动)单元格,这是cell.contentView的直接子视图。我的代码逻辑是这样的(为了更好地理解而修改):

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    UITableViewCell *previousActiveCell = [tableView cellForRowAtIndexPath:_indexPathActiveCell]; // previous selection
    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath: indexPath]; // current selection

    UILabel *labelpreviousActiveCellTitle = [previousActiveCell.contentView viewWithTag:SUBVIEW_TAG_TITLE_LABEL];
    UILabel *labelSelectedCellTitle = [selectedCell.contentView viewWithTag:SUBVIEW_TAG_TITLE_LABEL];

    labelpreviousActiveCellTitle.backgroundColor = [UIColor clearColor]; // remove highlighting from previous selection
    labelSelectedCellTitle.backgroundColor = [UIColor redColor]; // highlighted

    _indexPathActiveCell = indexPath; // update _indexPathActiveCell with current selection
}

问题是,当选择新单元格时,突出显示的背景颜色会出现很短的时间,大约半秒钟,然后消失。如果我注释掉deselectRowAtIndexPath的调用,

// [tableView deselectRowAtIndexPath:indexPath animated:YES];

突出显示背景颜色将保留。我的猜测是deselectRowAtIndexPath 记住 所有子视图的先前背景颜色,当它从阴影背景中恢复单元格时,它会更改所有子视图的背景颜色。

我的解决方法是添加这样的延迟:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    labelpreviousActiveCellTitle.backgroundColor = [UIColor clearColor];
    labelSelectedCellTitle.backgroundColor = [UIColor redColor];
});

它有效。请注意,我也尝试了较短的延迟,如0.01秒,但没有效果。

使用幻数设置延迟时间是一种令人不快的方式。我的问题是,有没有更好的方法在tableview的didSelectRowAtIndexPath委托方法中设置单元格子视图的背景颜色?提前谢谢。

2 个答案:

答案 0 :(得分:1)

您是否尝试过创建一个继承自UITableViewCell的自定义单元格?

自定义单元格将标签作为公共属性,因此您可以从控制器引用标签,而无需标记。

答案 1 :(得分:1)

创建一个临时变量,用于保存视图控制器中的选定单元格。我正在使用自定义单元格。虽然

,但这并不重要
var selectedCellIndex:IndexPath?
你的viewDidLoad中的

就像这样初始化。

selectedCellIndex = IndexPath.init(row: -1, section: 0)// first row starts with 0 you know.
你的cellForRowAtIndexPath函数中的

就像这样修改它。

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "chatCell", for: indexPath) as! sampleTableViewCell


    if indexPath.row == selectedCellIndex?.row {
        cell.label.backgroundColor = UIColor.green
    }
    else {
        cell.label.backgroundColor = UIColor.clear
    }       
    cell.selectionStyle = .none //For removing grey color while cell selection.
    return cell

}

像这样更改你的didSelectRowAtIndexPath。

public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    selectedCellIndex = indexPath
    tableView.reloadRows(at: tableView.indexPathsForVisibleRows!, with: .none) //reload only visible cells. don't call reloadData it's expensive.

}

这是输出:

enter image description here