如何将渐变层放置到没有框架的 UIImageView 上

Posted

技术标签:

【中文标题】如何将渐变层放置到没有框架的 UIImageView 上【英文标题】:How to place a gradient layer onto a UIImageView that has no frame 【发布时间】:2019-05-06 05:09:38 【问题描述】:

我正在尝试在我的 ios 应用程序中的图像上放置灰色透明渐变,但由于框架问题,它不起作用。由于我的UIImageView 是通过编程方式设置并使用translatesAutoresizingMaskIntoConstraints = false 设置的,因此当我将其框架设置为图像框架时,渐变层是不可见的。我不想将任一帧设置为常量,因为图像位于集合视图单元格中,该单元格使用sizeForItemAt 函数来确定每个单元格的大小,因此图像的大小会随着单元格,我需要我的渐变具有与图像相同的大小。

我试图通过创建一个UIView 来设置渐变,我将其放置为UIImageView 的子视图,但由于框架再次出现问题而没有运气。我看过其他关于添加渐变层的帖子,但它们都要求我为渐变定义一个框架。

//This is the imageview and the gradient that I want to apply to it
let profileImageView: UIImageView = 
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.translatesAutoresizingMaskIntoConstraints = false
        return imageView
     ()
var gradient: CAGradientLayer = 
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = [UIColor.clear.cgColor,    UIColor.gray.cgColor]
        gradientLayer.opacity = 0.7
        return gradientLayer
    ()

//This is the setupviews() function where I apply the gradient to the imageview
func setupViews() 
        self.contentView.addSubview(profileImageView)
        profileImageView.layer.addSublayer(gradient)

        //constraints for profileImageView
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[v0]-0-|", options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: ["v0": profileImageView]))

        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[v0]-0-|", options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: ["v0": profileImageView]))

目前为了显示渐变,我需要在setupViews() 中为渐变层定义一个框架,但正如我之前所述,我不想这样做。有没有一种方法可以在不定义特定框架的情况下创建渐变层,或者在我的情况下是否有另一种更好的方法来应用渐变层?谢谢!

编辑:我想澄清一下,我的 UICollectionViewCell 类中的所有视图都没有框架。它们都以编程方式设置了约束,因此如果我尝试打印view.frame.heightview.frame.width,尽管视图的实际高度和宽度不为零,但程序将打印为零。因此,为渐变定义任何类型的框架或将渐变的框架设置为视图的框架都不起作用。我是否必须重新构建视图的设置方式才能在图像上放置渐变?或者我还能希望从这个问题中得到救赎吗?谢谢!

【问题讨论】:

【参考方案1】:

您可以: - 使用以下代码创建一个 Swift 文件 - 将您的 imageView 设置为此类 - 将此 imageView 或 UIView(在这种情况下相应地转动类)放在包含您的图像的 UIImageView 上方。 它应该可以工作(参见示例截图)。 根据您的颜色/alpha 设置修改参数。 希望它会有所帮助。

import Foundation
import UIKit

class AddGradientsToImageView: UIImageView 

// For item created programmatically
override init(frame: CGRect) 
    super.init(frame: frame)

    addGradientsToImageView()


// For items created in the storyboard
required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)
    addGradientsToImageView()


func addGradientsToImageView() 

// Set background gradient colors
let lightBlue = UIColor(red: 112/255, green: 117/255, blue: 239/255, alpha: 1)
let darkBlue = UIColor(red: 70/255, green: 84/255, blue: 201/255, alpha: 1)

// Set gradients
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.colors = [darkBlue.cgColor, lightBlue.cgColor]
gradientLayer.locations = [0.0,1.0]
gradientLayer.startPoint = CGPoint(x: 1.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)

// Clip gradients to background bounds
clipsToBounds = true

// Set transparency level
alpha = 0.50

// insert gradients to button
layer.insertSublayer(gradientLayer, at: 0)


result of the code to this imageView result of the code with a picture behind

【讨论】:

我认为这需要我为渐变定义一个框架? 是的,您可能需要保留一个框架,但可能不需要为渐变层指定任何大小;你试过clipsToBounds你的渐变吗?好吧,无论图片的大小是什么,我都能从上面得到什么。【参考方案2】:

你可以创建一个继承自 UIImageView 的自定义类,创建时添加图层,并覆盖 layoutsubviews()

override func layoutSubviews() 
   super.layoutSubviews()
   customlayer.frame = self.bounds     

【讨论】:

【参考方案3】:

也许你会尝试访问sizeForItem中的UIImageView,然后你会在那个方法中调整渐变子层的大小?

【讨论】:

以上是关于如何将渐变层放置到没有框架的 UIImageView 上的主要内容,如果未能解决你的问题,请参考以下文章

将渐变层添加到表格视图

为啥我的渐变子层显示奇怪?

在表格视图单元格背景上放置渐变

如何修复不一致的颜色到清晰的径向渐变层

将渐变层添加到具有相同名称 Xcode/Swift 的所有按钮

Flutter - 如何将图像与渐变颜色混合?