奇怪的 UITableViewCell 阴影行为

Strange UITableViewCell shadow behaviour

我正在尝试向单个 UITableViewCell 添加阴影。我在自定义单元格子类中使用此代码:

override func layoutSubviews() {
    super.layoutSubviews()

    layer.masksToBounds = false
    layer.shadowOffset = CGSize(width: 0, height: 1)
    layer.shadowColor = UIColor.black.cgColor
    layer.shadowOpacity = 0.9
    layer.shadowRadius = 10
    layer.shadowPath = CGPath(rect: bounds, transform: nil)
}

但阴影通常只出现在单元格的 bottom/top 边缘,并且在滚动过程中会发生变化。

有人可以帮我吗?

layoutSubviews() 不适合这样的 UI 设置。 由于您只需要将阴影添加到某些特定的单元格,因此在用数据填充单元格时应用或删除它。不要忘记去掉不需要的阴影,否则cell重复使用时,阴影会留下来。

您看不到阴影,因为单元格 above/below 在 view-hierarchy 中更高,具体取决于它是在自定义单元格之前还是之后出列。查看 Xcode 中的 View-Hierarchy-Debugger 以发现问题。

您有几个可能的解决方案,但我将在这里概述其中的两个:

  1. 您可以在 tableView 中使用 bringSubviewToFront 以确保您的自定义单元格始终位于顶部。
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if cell.isKind(of: MyCustomShadowCell.self) {
        tableView.bringSubviewToFront(cell)
    }
}
  1. 另一种解决方案是将单元格的 layer.zPosition 设置为较高的值,以便它始终位于顶部。我觉得有点 hack-ish 但如果你想尝试:layer.zPosition = CGFloat.greatestFiniteMagnitude.

您的影子必须包含在您的单元格范围内。发生的事情是你的影子实际上超出了你的单元格边界,当单元格被重用并放置在 table 视图中时,下一个单元格会覆盖你的阴影。当您上下滚动时,单元格将以不同的顺序再次重复使用,具体取决于您的影子是否出现。

尝试更改这行代码

layer.shadowPath = CGPath(rect: bounds, transform: nil)

至此

layer.shadowPath = CGPath(rect: .init(x: 0,
                                  y: 10,
                                  width: contentView.bounds.width,
                                  height: contentView.bounds.height - 20),
                      transform: nil)

这会将你的影子放在边界内,但我认为它看起来不如我的下一个建议。

我给你的第二个建议是创建另一个父视图来保存你的单元格子视图。然后将其添加为单元格 contentView 的子视图,并将阴影应用于父视图层而不是单元格的 contentView。确保父视图从顶部到底部有 10 的填充,你将实现你想要的。