CAGradientLayer 不显示
CAGradientLayer does not display
我查看了很多其他类似问题的答案,但 none 的答案似乎解决了我的问题,因此寻求一点帮助。
我正在尝试将垂直渐变应用到 UIButton,但渐变层没有显示在我的视图中。相关代码如下:
let darkPurple = UIColor(displayP3Red: 61.0/255.0, green: 3.0/255.0, blue: 110.0/255.0, alpha: 1.0)
let lightPurple = UIColor(displayP3Red: 90.0/255.0, green: 32.0/255.0, blue: 130.0/255.0, alpha: 1.0)
let addButton = UIButton(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
addButton.title = "Start counting"
addButton.layer.cornerRadius = 30.0
addButton.layer.borderWidth = 1.0
addButton.layer.borderColor = darkPurple.cgColor
addButton.translatesAutoresizingMaskIntoConstraints = false
myView.addSubview(addButton)
addButton.applyGradient(with: [lightPurple, darkPurple], gradientOrientation: .vertical)
...以及应用渐变的代码:
typealias GradientPoints = (startPoint: CGPoint, endPoint: CGPoint)
enum GradientOrientation {
case topRightBottomLeft
case topLeftBottomRight
case horizontal
case vertical
var startPoint: CGPoint {
return points.startPoint
}
var endPoint: CGPoint {
return points.endPoint
}
var points: GradientPoints {
switch self {
case .topRightBottomLeft:
return (CGPoint(x: 0.0, y: 1.0), CGPoint(x: 1.0, y: 0.0))
case .topLeftBottomRight:
return (CGPoint(x: 0.0, y: 0.0), CGPoint(x: 1.0, y: 1.0))
case .horizontal:
return (CGPoint(x: 0.0, y: 0.0), CGPoint(x: 1.0, y: 0.0))
case .vertical:
return (CGPoint(x: 0.0, y: 0.0), CGPoint(x: 0.0, y: 1.0))
}
}
}
extension UIView {
func applyGradient(with colors: [UIColor], gradientOrientation orientation: GradientOrientation) {
let gradient = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = colors.map { [=11=].cgColor }
gradient.startPoint = orientation.startPoint
gradient.endPoint = orientation.endPoint
gradient.borderColor = self.layer.borderColor
gradient.borderWidth = self.layer.borderWidth
gradient.cornerRadius = self.layer.cornerRadius
gradient.masksToBounds = true
gradient.isHidden = false
self.layer.insertSublayer(gradient, at: 0)
}
}
这是我得到的:
empty button
感谢您的帮助!
子层按从后到前的顺序排列。在索引 0 处插入层会将其放置在任何其他子层之后。我从来没有尝试用按钮来做到这一点,但怀疑它至少有 1 个子层覆盖了您要添加的渐变。
尝试使用 addSublayer()
,这会将层放在子层数组的顶部。
编辑:
我构建了您的代码的一个变体,当我将 self.layer.insertSublayer(_:at:)
更改为 addSublayer()
时,它起作用了。
自动布局不影响 UIView
对象的图层,因此在计算 UIButton
的帧之前过早应用渐变图层。当渐变层的frame
属性被赋值时,按钮的bounds仍然等于CGRect.zero
,之后渐变层的边框永远不会更新。
您会发现,如果在计算按钮框架后添加渐变层,它会按预期工作。例如:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let darkPurple = UIColor(displayP3Red: 61.0/255.0, green: 3.0/255.0, blue: 110.0/255.0, alpha: 1.0)
let lightPurple = UIColor(displayP3Red: 90.0/255.0, green: 32.0/255.0, blue: 130.0/255.0, alpha: 1.0)
addButton.applyGradient(with: [lightPurple, darkPurple], gradientOrientation: .vertical)
}
另一种选择是更新 viewDidLayoutSubviews()
中渐变层的 frame
属性 或创建自定义 UIButton
子类并在任何时候更新渐变层框架按钮的框架更新。
对于已经花费数小时搜索(就像我一样)的任何人:
请确保您的颜色数组包含 CGColor
而不是 UIColor
,根据文档:
colors
An array of CGColorRef objects defining the color of each
gradient stop. Animatable.
https://developer.apple.com/documentation/quartzcore/cagradientlayer/1462403-colors
我查看了很多其他类似问题的答案,但 none 的答案似乎解决了我的问题,因此寻求一点帮助。
我正在尝试将垂直渐变应用到 UIButton,但渐变层没有显示在我的视图中。相关代码如下:
let darkPurple = UIColor(displayP3Red: 61.0/255.0, green: 3.0/255.0, blue: 110.0/255.0, alpha: 1.0)
let lightPurple = UIColor(displayP3Red: 90.0/255.0, green: 32.0/255.0, blue: 130.0/255.0, alpha: 1.0)
let addButton = UIButton(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
addButton.title = "Start counting"
addButton.layer.cornerRadius = 30.0
addButton.layer.borderWidth = 1.0
addButton.layer.borderColor = darkPurple.cgColor
addButton.translatesAutoresizingMaskIntoConstraints = false
myView.addSubview(addButton)
addButton.applyGradient(with: [lightPurple, darkPurple], gradientOrientation: .vertical)
...以及应用渐变的代码:
typealias GradientPoints = (startPoint: CGPoint, endPoint: CGPoint)
enum GradientOrientation {
case topRightBottomLeft
case topLeftBottomRight
case horizontal
case vertical
var startPoint: CGPoint {
return points.startPoint
}
var endPoint: CGPoint {
return points.endPoint
}
var points: GradientPoints {
switch self {
case .topRightBottomLeft:
return (CGPoint(x: 0.0, y: 1.0), CGPoint(x: 1.0, y: 0.0))
case .topLeftBottomRight:
return (CGPoint(x: 0.0, y: 0.0), CGPoint(x: 1.0, y: 1.0))
case .horizontal:
return (CGPoint(x: 0.0, y: 0.0), CGPoint(x: 1.0, y: 0.0))
case .vertical:
return (CGPoint(x: 0.0, y: 0.0), CGPoint(x: 0.0, y: 1.0))
}
}
}
extension UIView {
func applyGradient(with colors: [UIColor], gradientOrientation orientation: GradientOrientation) {
let gradient = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = colors.map { [=11=].cgColor }
gradient.startPoint = orientation.startPoint
gradient.endPoint = orientation.endPoint
gradient.borderColor = self.layer.borderColor
gradient.borderWidth = self.layer.borderWidth
gradient.cornerRadius = self.layer.cornerRadius
gradient.masksToBounds = true
gradient.isHidden = false
self.layer.insertSublayer(gradient, at: 0)
}
}
这是我得到的: empty button
感谢您的帮助!
子层按从后到前的顺序排列。在索引 0 处插入层会将其放置在任何其他子层之后。我从来没有尝试用按钮来做到这一点,但怀疑它至少有 1 个子层覆盖了您要添加的渐变。
尝试使用 addSublayer()
,这会将层放在子层数组的顶部。
编辑:
我构建了您的代码的一个变体,当我将 self.layer.insertSublayer(_:at:)
更改为 addSublayer()
时,它起作用了。
自动布局不影响 UIView
对象的图层,因此在计算 UIButton
的帧之前过早应用渐变图层。当渐变层的frame
属性被赋值时,按钮的bounds仍然等于CGRect.zero
,之后渐变层的边框永远不会更新。
您会发现,如果在计算按钮框架后添加渐变层,它会按预期工作。例如:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let darkPurple = UIColor(displayP3Red: 61.0/255.0, green: 3.0/255.0, blue: 110.0/255.0, alpha: 1.0)
let lightPurple = UIColor(displayP3Red: 90.0/255.0, green: 32.0/255.0, blue: 130.0/255.0, alpha: 1.0)
addButton.applyGradient(with: [lightPurple, darkPurple], gradientOrientation: .vertical)
}
另一种选择是更新 viewDidLayoutSubviews()
中渐变层的 frame
属性 或创建自定义 UIButton
子类并在任何时候更新渐变层框架按钮的框架更新。
对于已经花费数小时搜索(就像我一样)的任何人:
请确保您的颜色数组包含 CGColor
而不是 UIColor
,根据文档:
colors
An array of CGColorRef objects defining the color of each gradient stop. Animatable.
https://developer.apple.com/documentation/quartzcore/cagradientlayer/1462403-colors