奇怪的 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 以发现问题。
您有几个可能的解决方案,但我将在这里概述其中的两个:
- 您可以在
tableView
中使用 bringSubviewToFront
以确保您的自定义单元格始终位于顶部。
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell.isKind(of: MyCustomShadowCell.self) {
tableView.bringSubviewToFront(cell)
}
}
- 另一种解决方案是将单元格的
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 的填充,你将实现你想要的。
我正在尝试向单个 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 以发现问题。
您有几个可能的解决方案,但我将在这里概述其中的两个:
- 您可以在
tableView
中使用bringSubviewToFront
以确保您的自定义单元格始终位于顶部。
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell.isKind(of: MyCustomShadowCell.self) {
tableView.bringSubviewToFront(cell)
}
}
- 另一种解决方案是将单元格的
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 的填充,你将实现你想要的。