通过 CAGradientLayer 在 IOS 中向 UIImageView 添加渐变层
Add Gradient Layer to UIImageView in IOS thru CAGradientLayer
我正在尝试在 IOS 中添加渐变,就像我在 Android 中所做的那样。所以我可以在 UIImageView 的顶部看到我的标签并且它没有隐藏。
在 android 中,我在可绘制的`
中完成了此操作
<gradient
android:angle="90"
android:endColor="#00ffffff"
android:startColor="#aa000000"
android:centerColor="#00ffffff" />
<corners android:radius="0dp" />
`
我正在尝试在 IOS Swift 4.2 中执行此操作,我得到以下信息:
let gradient: CAGradientLayer = CAGradientLayer()
gradient.colors = [UIColor.blue.cgColor, UIColor.red.cgColor]
gradient.locations = [0.0 , 1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
gradient.endPoint = CGPoint(x: 0.5, y: 0.5)
gradient.frame = CGRect(x: 0.0, y: 0.0, width: showImageView.frame.size.width, height: showImageView.frame.size.height)
showImageView.layer.addSublayer(gradient)
如何让渐变从底部开始变黑并以 90 度上升?如何更改不透明度?有什么想法吗?
一些想法:
选择alpha
小于1的颜色。也许:
gradient.colors = [
UIColor.black.withAlphaComponent(0.8).cgColor,
UIColor.black.withAlphaComponent(0).cgColor
]
要使此渐变垂直,请选择具有相同 x
值的起点和终点。例如。覆盖下半部分,也许:
gradient.startPoint = CGPoint(x: 0.5, y: 1)
gradient.endPoint = CGPoint(x: 0.5, y: 0.5)
使用 frame
时要非常小心。您希望图层引用图像视图的 bounds
(使用图像视图的坐标系),而不是 frame
(指定图像视图在其父视图的坐标系中的位置)。如果你的图像视图恰好在 0, 0
,你可能看不出有什么不同,但如果你移动图像视图,这些就会开始偏离。因此,假设您要将此渐变添加到图像视图本身,您将使用图像视图的边界:
gradient.frame = showImageView.bounds
请注意,图像视图的 frame
/bounds
有时会发生变化。因此,我们将在 UIImageView
或 UITableViewCell
子类中实现 layoutSubviews
,并在那里更新梯度的 frame
,例如
override func layoutSubviews() {
super.layoutSubviews()
gradient.frame = bounds
}
这样它将在视图布局更改时更新渐变 frame
。
另一种解决方案是定义一个 UIView
子类,比如 GradientView
,它呈现 CAGradientLayer
并将该视图的基础 layerClass
定义为 CAGradientLayer
。然后在图像视图和标签之间添加这个视图,定义它的约束,然后你将拥有一个随着 GradientView
大小变化而动态变化的渐变。 (这种 layerClass
方法的优点是它比仅以编程方式更新 frame
产生更好的 animation/transitions。)
因此,类似于:
class GradientView: UIView {
override class var layerClass: AnyClass { return CAGradientLayer.self }
var gradientLayer: CAGradientLayer { return layer as! CAGradientLayer }
var firstColor: UIColor = UIColor.black.withAlphaComponent(0.8) {
didSet { updateColors() }
}
var secondColor: UIColor = UIColor.black.withAlphaComponent(0) {
didSet { updateColors() }
}
override init(frame: CGRect = .zero) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}
}
private extension GradientView {
func configure() {
updateColors()
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.5)
}
func updateColors() {
gradientLayer.colors = [firstColor, secondColor].map { [=14=].cgColor }
}
}
如果您真的想让白色文本突出显示,除了在图像上添加渐变之外,您还可以在文本中添加黑色 glow/shadow。它很微妙,但确实使文本流行起来。只需使其阴影颜色与渐变颜色相同即可。
所以你可以看到效果,这是一个单元格的四个再现,(a)没有渐变; (b) 有梯度; (c) 在文本周围使用渐变和漂亮的高斯模糊;和 (d) 文本周围有简单的阴影:
文本周围漂亮的高斯模糊是通过以下方式呈现的:
customLabel.layer.shadowColor = UIColor.black.cgColor
customLabel.layer.shadowRadius = 3
customLabel.layer.shadowOpacity = 1
customLabel.layer.masksToBounds = false
customLabel.layer.shouldRasterize = true
我认为第三个再现(图像上有渐变,文本周围有光晕)最好。它很微妙,但文字确实很流行。但是高斯模糊在计算上是昂贵的,所以如果你发现这对你的性能有太大的不利影响,你可以使用第四个选项,使用简单的、非模糊的阴影:
customLabel.shadowColor = .black
// perhaps also
// customLabel.shadowOffset = CGSize(width: -1, height: -1)
我正在尝试在 IOS 中添加渐变,就像我在 Android 中所做的那样。所以我可以在 UIImageView 的顶部看到我的标签并且它没有隐藏。
在 android 中,我在可绘制的`
中完成了此操作<gradient
android:angle="90"
android:endColor="#00ffffff"
android:startColor="#aa000000"
android:centerColor="#00ffffff" />
<corners android:radius="0dp" />
`
我正在尝试在 IOS Swift 4.2 中执行此操作,我得到以下信息:
let gradient: CAGradientLayer = CAGradientLayer()
gradient.colors = [UIColor.blue.cgColor, UIColor.red.cgColor]
gradient.locations = [0.0 , 1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
gradient.endPoint = CGPoint(x: 0.5, y: 0.5)
gradient.frame = CGRect(x: 0.0, y: 0.0, width: showImageView.frame.size.width, height: showImageView.frame.size.height)
showImageView.layer.addSublayer(gradient)
如何让渐变从底部开始变黑并以 90 度上升?如何更改不透明度?有什么想法吗?
一些想法:
选择
alpha
小于1的颜色。也许:gradient.colors = [ UIColor.black.withAlphaComponent(0.8).cgColor, UIColor.black.withAlphaComponent(0).cgColor ]
要使此渐变垂直,请选择具有相同
x
值的起点和终点。例如。覆盖下半部分,也许:gradient.startPoint = CGPoint(x: 0.5, y: 1) gradient.endPoint = CGPoint(x: 0.5, y: 0.5)
使用
frame
时要非常小心。您希望图层引用图像视图的bounds
(使用图像视图的坐标系),而不是frame
(指定图像视图在其父视图的坐标系中的位置)。如果你的图像视图恰好在0, 0
,你可能看不出有什么不同,但如果你移动图像视图,这些就会开始偏离。因此,假设您要将此渐变添加到图像视图本身,您将使用图像视图的边界:gradient.frame = showImageView.bounds
请注意,图像视图的
frame
/bounds
有时会发生变化。因此,我们将在UIImageView
或UITableViewCell
子类中实现layoutSubviews
,并在那里更新梯度的frame
,例如override func layoutSubviews() { super.layoutSubviews() gradient.frame = bounds }
这样它将在视图布局更改时更新渐变
frame
。另一种解决方案是定义一个
UIView
子类,比如GradientView
,它呈现CAGradientLayer
并将该视图的基础layerClass
定义为CAGradientLayer
。然后在图像视图和标签之间添加这个视图,定义它的约束,然后你将拥有一个随着GradientView
大小变化而动态变化的渐变。 (这种layerClass
方法的优点是它比仅以编程方式更新frame
产生更好的 animation/transitions。)因此,类似于:
class GradientView: UIView { override class var layerClass: AnyClass { return CAGradientLayer.self } var gradientLayer: CAGradientLayer { return layer as! CAGradientLayer } var firstColor: UIColor = UIColor.black.withAlphaComponent(0.8) { didSet { updateColors() } } var secondColor: UIColor = UIColor.black.withAlphaComponent(0) { didSet { updateColors() } } override init(frame: CGRect = .zero) { super.init(frame: frame) configure() } required init?(coder: NSCoder) { super.init(coder: coder) configure() } } private extension GradientView { func configure() { updateColors() gradientLayer.startPoint = CGPoint(x: 0.5, y: 1) gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.5) } func updateColors() { gradientLayer.colors = [firstColor, secondColor].map { [=14=].cgColor } } }
如果您真的想让白色文本突出显示,除了在图像上添加渐变之外,您还可以在文本中添加黑色 glow/shadow。它很微妙,但确实使文本流行起来。只需使其阴影颜色与渐变颜色相同即可。
所以你可以看到效果,这是一个单元格的四个再现,(a)没有渐变; (b) 有梯度; (c) 在文本周围使用渐变和漂亮的高斯模糊;和 (d) 文本周围有简单的阴影:
文本周围漂亮的高斯模糊是通过以下方式呈现的:
customLabel.layer.shadowColor = UIColor.black.cgColor customLabel.layer.shadowRadius = 3 customLabel.layer.shadowOpacity = 1 customLabel.layer.masksToBounds = false customLabel.layer.shouldRasterize = true
我认为第三个再现(图像上有渐变,文本周围有光晕)最好。它很微妙,但文字确实很流行。但是高斯模糊在计算上是昂贵的,所以如果你发现这对你的性能有太大的不利影响,你可以使用第四个选项,使用简单的、非模糊的阴影:
customLabel.shadowColor = .black // perhaps also // customLabel.shadowOffset = CGSize(width: -1, height: -1)