【问题标题】:UITableView's deselectRowAtIndexPath prevents cell's subviews from changing background colorUITableView 的 deselectRowAtIndexPath 防止单元格的子视图改变背景颜色
【发布时间】:2017-06-08 16:28:36
【问题描述】:

我正在开发带有自定义单元格的表格视图。我需要通过设置标题标签的背景颜色来突出显示当前选定的(活动)单元格,这是 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
}

The problem is, when a new cell is selected, the highlighting background color appears for a very short moment, about half a second, and then disappears.如果我注释掉对 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 委托方法中设置单元格子视图的背景颜色?提前致谢。

【问题讨论】:

  • 为什么不覆盖您的 CustomCollectionViewCell 的 setSelected:,并在那里放置正确的代码?不要忘记在prepareForReuse 中删除它,并在cellForRowAtIndexPath: 中将单元格标记为选中(如果需要)(因为滚动)。
  • 有些人可能会建议通过 tableview 的 reloadData 方法更新突出显示。在我的具体情况下,我避免这样做,因为更新是一个耗时的过程,并且有明显的延迟。
  • 不,我不知道。您的 CustomCollectionViewCell 有一个文件 (h,m)。不?用好颜色覆盖setSelected:
  • 哇!很好的解决方案!非常感谢 Larme!
  • @kuang:希望你能理解。

标签: ios uitableview


【解决方案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.

}

这是输出:

【讨论】:

  • 哦,是的,另一个很棒的解决方案!非常感谢!
【解决方案2】:

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

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

【讨论】:

  • 是的,它是通过从 UITableViewCell 继承创建的,我将尝试访问公共属性。谢谢!
猜你喜欢
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
  • 2014-10-21
  • 2020-04-28
  • 1970-01-01
相关资源
最近更新 更多