ios - 通过 CAGradientLayer 在 IOS 的 UIImageView 中添加渐变层

标签 ios swift uiimageview uilabel gradient

我正在尝试像在 Android 中那样在 IOS 中添加渐变.所以我可以在 UIImageView 的顶部看到我的标签并且它没有隐藏。

enter image description here

在 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)

enter image description here

如何让渐变从底部开始变黑并以 90 度上升?如何更改不透明度?有什么想法吗?

最佳答案

一些想法:

  1. 选择 alpha 小于 1 的颜色。也许:

    gradient.colors = [
        UIColor.black.withAlphaComponent(0.8).cgColor,
        UIColor.black.withAlphaComponent(0).cgColor
    ]
    
  2. 要使此渐变垂直,请选择具有相同 x 值的起点和终点。例如。覆盖下半部分,也许:

    gradient.startPoint = CGPoint(x: 0.5, y: 1)
    gradient.endPoint = CGPoint(x: 0.5, y: 0.5)
    
  3. 使用 frame 时要非常小心。您希望图层引用 ImageView 的 bounds(使用 ImageView 的坐标系),而不是 frame(它指定 ImageView 在其父 View 坐标中的位置系统)。如果您的 ImageView 恰好位于 0, 0,您可能看不出有什么不同,但如果您移动 ImageView ,它们就会开始偏离。因此,假设您要将此渐变添加到 ImageView 本身,您将使用 ImageView 的边界:

    gradient.frame = showImageView.bounds
    
  4. 请注意, ImageView 的 frame/bounds 有时会发生变化。因此,我们将在 UIImageViewUITableViewCell 子类中实现 layoutSubviews,并在那里更新渐变的 frame,例如

    override func layoutSubviews() {
        super.layoutSubviews()
        gradient.frame = bounds
    }
    

    这样它会在 View 布局更改时更新渐变的 frame

    另一种解决方案是定义一个 UIView 子类,比如 GradientView,它呈现 CAGradientLayer 并定义基础 layerClass 是一个 CAGradientLayer。然后在 ImageView 和标签之间添加此 View ,定义其约束,然后您将拥有一个随着 GradientView 大小变化而动态变化的渐变。 (这种 layerClass 方法的优势在于,与仅以编程方式更新 frame 相比,它可以产生更好的动画/过渡效果。)

    因此,类似于:

    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 { $0.cgColor }
        }
    }
    
  5. 如果您真的想让白色文本突出显示,除了在图像上添加渐变之外,您还可以向文本添加黑色发光/阴影。它很微妙,但确实使文本流行起来。只需使其阴影颜色与渐变颜色相同即可。

    所以你可以看到效果,这里有一个单元格的四个再现,其中 (a) 没有渐变; (b) 有梯度; (c) 在文本周围使用渐变和漂亮的高斯模糊;和 (d) 文本周围有简单的阴影:

    enter image description here

    文本周围漂亮的高斯模糊渲染为:

    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 - 通过 CAGradientLayer 在 IOS 的 UIImageView 中添加渐变层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54755209/

相关文章:

ios - 使用 SKShader 修改单个像素

ios - 从第二个 View 在第一个 View 中的初始功能(快速)

swift - 以编程方式在 ScrollView 中获取 UIImageView 时遇到问题

ios - 如何裁剪 UIScrollView 中显示的 UIImageView 部分并将其保存到 UIImage 变量?

iphone - 每次点击不同的图像

ios - 使用 Firebase 时,我应该什么时候在主线程上进行用户界面工作?

ios - 如何从 iPhone 应用程序向 Web 服务器写入数据?

ios - Spritekit Action 并不适用于所有设备

iphone - 从 iPhone 应用程序中删除自动续订订阅

ios - 如何在 Swift 4 中解析 A​​lamofire 中的数据