在 heightForRowAt IndexPath 之后 UITableViewCell 的层没有得到更新
Posted
技术标签:
【中文标题】在 heightForRowAt IndexPath 之后 UITableViewCell 的层没有得到更新【英文标题】:UITableViewCell's layer not getting updated after heightForRowAt IndexPath 【发布时间】:2017-09-21 00:37:49 【问题描述】:我正在更改每个 TableViewCell 的大小:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return 60
然后,在自定义单元格类中,我将“gradientLayer”作为子层插入到单元格的图层属性中:
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
...
gradientLayer.frame = self.layer.bounds
layer.insertSublayer(gradientLayer, at: 0)
...
但是,渐变并没有填满整个单元格:
有谁知道为什么会发生这种情况/我该如何解决?
谢谢。
【问题讨论】:
【参考方案1】:如果您使用普通的UITableViewCell
:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return 100.0
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
// ...
let gradient = CAGradientLayer()
gradient.frame = cell.contentView.frame
gradient.colors = [UIColor.blue.cgColor, UIColor.yellow.cgColor]
gradient.locations = [0.0, 1.0]
cell.contentView.layer.insertSublayer(gradient, at: 0)
// ...
return cell
您需要确保将渐变添加到 contentView 的图层。
这会很好用。
如果您使用自定义 UITableViewCell
类:
现在,如果您使用的是自定义单元格类,则需要覆盖layoutSubviews()
方法,如下所示:
override func layoutSubviews()
super.layoutSubviews()
gradient.frame = contentView.frame
这可确保您的渐变框架在任何时候都与您的 contentView 框架相同。
您的自定义单元格类将如下所示:
class CustomTableCell: UITableViewCell
lazy var gradient : CAGradientLayer =
var gradient = CAGradientLayer()
gradient.colors = [UIColor.blue.cgColor, UIColor.yellow.cgColor]
gradient.locations = [0.0, 1.0]
self.contentView.layer.insertSublayer(gradient, at: 0)
return gradient
()
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
// ...
override func layoutSubviews()
super.layoutSubviews()
// ...
gradient.frame = contentView.frame
// ...
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
// ...
如果您有任何其他问题,请告诉我!
【讨论】:
在 init 中设置框架不正确。该点的框架将是单元格的默认框架,这可能不是 heightForRowAtIndexPath 返回的内容。 这就是我对 OP 说要在 layoutSubviews() 中设置的原因! 请不要介意我的复制/粘贴错误,我更新了答案:)。 您显示的初始化代码在这两种情况下都不正确。这就是我的观点。由于尚未应用 heightForRowAtIndexPath,因此永远不应使用该框架。 这对我有用,我相信这对我来说是正确的选择,因为我使用的是自定义单元格。再次感谢您。【参考方案2】:为什么会这样?我不知道。
但是如果你把渐变放在你的 tableview 的cellForRowAt
中,你会得到:
代码如下:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return 60
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let gradient: CAGradientLayer = CAGradientLayer()
gradient.colors = [UIColor.blue.cgColor, UIColor.red.cgColor]
gradient.frame = CGRect(x: 0.0, y: 0.0, width: cell.frame.size.width, height: cell.frame.size.height)
cell.layer.insertSublayer(gradient, at: 0)
return cell
【讨论】:
没错,这就是我要向@clarus 解释的内容。在调用 cellForRow 方法时,您的 heightForRow 已经运行,因此您可以在此方法中设置渐变框架而不会出现任何问题。【参考方案3】:初始时的帧大小是单元格的默认帧,来自故事板或任何地方。它不会有你的高度 60(除非匹配),因为单元格只是在 init 中创建,然后它将被调整大小。
您可以在那里添加图层,但在 layoutSubviews 中调整大小或使用约束来自动布局。如果您这样做,渐变将以最终大小填充您的单元格。
【讨论】:
以上是关于在 heightForRowAt IndexPath 之后 UITableViewCell 的层没有得到更新的主要内容,如果未能解决你的问题,请参考以下文章
EXC_BAD_ACCESS 在 heightForRowAt 内时
RxSwift + UITableViewCell 如何在 heightForRowAt 中获取单元格对象
在 heightForRowAt IndexPath 之后 UITableViewCell 的层没有得到更新
indexpath.row 在tableView heightForRowAt 3 后重置
什么时候设置更改 heightForRowAt UITableView 动画被破坏
使 UITableViewCell 适合 UICollectionView 而没有 tableView heightForRowAt