具有渐变的 UITableViewCell 在第一次重用单元格之前不起作用
UITableViewCell with gradient not working until first reuse of cell
我想为自定义的一部分添加渐变 UITableViewCell
。这是我的渐变代码。
func addGradient() {
gradient = CAGradientLayer()
gradient.frame = CGRect(x: 0, y: 0, width: gradientView.frame.width, height: gradientView.frame.height)
gradient.colors = [
UIColor(red:0.23, green:0.24, blue:0.28, alpha:1).cgColor,
UIColor(red:0.11, green:0.11, blue:0.12, alpha:0.6).cgColor
]
gradient.locations = [0, 1]
gradient.startPoint = CGPoint(x: 0.5, y: 0)
gradient.endPoint = CGPoint(x: 0.5, y: 1)
gradientView.layer.addSublayer(gradient)
}
这是我的 gradientView 代码。
func addGradientView() {
containerView.addSubview(gradientView)
gradientView.translatesAutoresizingMaskIntoConstraints = false
gradientView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
gradientView.topAnchor.constraint(equalTo: barChart.bottomAnchor).isActive = true
gradientView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
gradientView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
}
addGradient()
在layoutSubiviews()
方法中调用。但是真正的高度和宽度似乎直到第一次重用单元格才反映出来。
选项 1: 从表视图的 willDisplayCell
委托方法中调用您的 addGradient()
。
public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell is YourCustomTableViewCell {
(cell as! YourCustomTableViewCell).addGradient()
}
}
确保添加一次渐变。由于小区重用 addGradient()
可能会在同一个小区上多次调用。所以最好将您的函数重命名为 addGradientfNeeded()
并相应地调整其逻辑。
选项 2:
不要在 willDisplay
方法中添加渐变,而是在单元格中添加渐变视图和图层(一次),并且只更新渐变图层的框架。
public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell is YourCustomTableViewCell {
(cell as! YourCustomTableViewCell).updateGradientLayerFrame()
}
}
选项 3:
创建一个 GradientView
class 并将其添加到界面生成器中或以编程方式添加到您的单元格中,渐变将随着视图框架的变化而调整大小:
public class GradientView: UIView {
private var gradientLayer: CAGradientLayer?
override public func layoutSubviews() {
super.layoutSubviews()
guard gradientLayer == nil else {
gradientLayer?.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
return
}
gradientLayer = CAGradientLayer()
gradientLayer!.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
gradientLayer!.colors = [
UIColor(red:0.23, green:0.24, blue:0.28, alpha:1).cgColor,
UIColor(red:0.11, green:0.11, blue:0.12, alpha:0.6).cgColor
]
gradientLayer!.locations = [0, 1]
gradientLayer!.startPoint = CGPoint(x: 0.5, y: 0)
gradientLayer!.endPoint = CGPoint(x: 0.5, y: 1)
self.layer.addSublayer(gradientLayer!)
}
}
您的 TableViewCell 还没有框架。您可以打印帧来检查,这将是一个零帧。
将 addGradientView 方法移动到 layoutSubView 覆盖。
override func layoutSubviews() {
super.layoutSubviews()
addGradient()
}
编辑:
我看到您提到它在 layoutSubView 中不起作用。我相信您调用该方法的方式存在一些问题。
下面的代码对我有用
class GradientCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
print(self.frame)
addGradient()
}
func addGradient() {
let gradient = CAGradientLayer()
gradient.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
gradient.colors = [
UIColor(red:0.23, green:0.24, blue:0.28, alpha:1).cgColor,
UIColor(red:0.11, green:0.11, blue:0.12, alpha:0.6).cgColor
]
gradient.locations = [0, 1]
gradient.startPoint = CGPoint(x: 0.5, y: 0)
gradient.endPoint = CGPoint(x: 0.5, y: 1)
self.layer.addSublayer(gradient)
}
}
编辑 2:
如果你移动 didMoveToWindow
会更好
在单元格内创建一个全局变量。
private let gradientLayer: CAGradientLayer = {
let layer = CAGradientLayer()
layer.colors = [UIColor.magenta.cgColor, UIColor.black.cgColor]
layer.locations = [0.0, 1.0]
layer.cornerRadius = 5
layer.masksToBounds = true
return layer
}()
然后在要添加 UI 组件的初始化方法中添加此渐变层。
现在你必须更新渐变层的框架。
override func layoutSubviews() {
super.layoutSubviews()
updateGradientFrame()
}
private func updateGradientFrame() {
gradientLayer.frame = // set your frame here...
}
我想为自定义的一部分添加渐变 UITableViewCell
。这是我的渐变代码。
func addGradient() {
gradient = CAGradientLayer()
gradient.frame = CGRect(x: 0, y: 0, width: gradientView.frame.width, height: gradientView.frame.height)
gradient.colors = [
UIColor(red:0.23, green:0.24, blue:0.28, alpha:1).cgColor,
UIColor(red:0.11, green:0.11, blue:0.12, alpha:0.6).cgColor
]
gradient.locations = [0, 1]
gradient.startPoint = CGPoint(x: 0.5, y: 0)
gradient.endPoint = CGPoint(x: 0.5, y: 1)
gradientView.layer.addSublayer(gradient)
}
这是我的 gradientView 代码。
func addGradientView() {
containerView.addSubview(gradientView)
gradientView.translatesAutoresizingMaskIntoConstraints = false
gradientView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
gradientView.topAnchor.constraint(equalTo: barChart.bottomAnchor).isActive = true
gradientView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
gradientView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
}
addGradient()
在layoutSubiviews()
方法中调用。但是真正的高度和宽度似乎直到第一次重用单元格才反映出来。
选项 1: 从表视图的 willDisplayCell
委托方法中调用您的 addGradient()
。
public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell is YourCustomTableViewCell {
(cell as! YourCustomTableViewCell).addGradient()
}
}
确保添加一次渐变。由于小区重用 addGradient()
可能会在同一个小区上多次调用。所以最好将您的函数重命名为 addGradientfNeeded()
并相应地调整其逻辑。
选项 2:
不要在 willDisplay
方法中添加渐变,而是在单元格中添加渐变视图和图层(一次),并且只更新渐变图层的框架。
public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell is YourCustomTableViewCell {
(cell as! YourCustomTableViewCell).updateGradientLayerFrame()
}
}
选项 3:
创建一个 GradientView
class 并将其添加到界面生成器中或以编程方式添加到您的单元格中,渐变将随着视图框架的变化而调整大小:
public class GradientView: UIView {
private var gradientLayer: CAGradientLayer?
override public func layoutSubviews() {
super.layoutSubviews()
guard gradientLayer == nil else {
gradientLayer?.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
return
}
gradientLayer = CAGradientLayer()
gradientLayer!.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
gradientLayer!.colors = [
UIColor(red:0.23, green:0.24, blue:0.28, alpha:1).cgColor,
UIColor(red:0.11, green:0.11, blue:0.12, alpha:0.6).cgColor
]
gradientLayer!.locations = [0, 1]
gradientLayer!.startPoint = CGPoint(x: 0.5, y: 0)
gradientLayer!.endPoint = CGPoint(x: 0.5, y: 1)
self.layer.addSublayer(gradientLayer!)
}
}
您的 TableViewCell 还没有框架。您可以打印帧来检查,这将是一个零帧。
将 addGradientView 方法移动到 layoutSubView 覆盖。
override func layoutSubviews() {
super.layoutSubviews()
addGradient()
}
编辑:
我看到您提到它在 layoutSubView 中不起作用。我相信您调用该方法的方式存在一些问题。 下面的代码对我有用
class GradientCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
print(self.frame)
addGradient()
}
func addGradient() {
let gradient = CAGradientLayer()
gradient.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
gradient.colors = [
UIColor(red:0.23, green:0.24, blue:0.28, alpha:1).cgColor,
UIColor(red:0.11, green:0.11, blue:0.12, alpha:0.6).cgColor
]
gradient.locations = [0, 1]
gradient.startPoint = CGPoint(x: 0.5, y: 0)
gradient.endPoint = CGPoint(x: 0.5, y: 1)
self.layer.addSublayer(gradient)
}
}
编辑 2: 如果你移动 didMoveToWindow
会更好在单元格内创建一个全局变量。
private let gradientLayer: CAGradientLayer = {
let layer = CAGradientLayer()
layer.colors = [UIColor.magenta.cgColor, UIColor.black.cgColor]
layer.locations = [0.0, 1.0]
layer.cornerRadius = 5
layer.masksToBounds = true
return layer
}()
然后在要添加 UI 组件的初始化方法中添加此渐变层。
现在你必须更新渐变层的框架。
override func layoutSubviews() {
super.layoutSubviews()
updateGradientFrame()
}
private func updateGradientFrame() {
gradientLayer.frame = // set your frame here...
}