[英]Applying gradient to UIImage
I want to apply color gradient(from top to bottom) to an image named 'newspaperImage'. 我想将颜色渐变(从上到下)应用于名为“ newspaperImage”的图像。 This is my code using swift language. 这是我使用快速语言的代码。
@IBOutlet weak var newspaperImage: UIImageView!
func imageGradient(){
let newspaperview = UIView(frame: newspaperImage.frame)
let gradient = CAGradientLayer()
gradient.frame = newspaperview.bounds
let startColor = UIColor(red: 30, green: 113, blue: 79, alpha: 0).cgColor
let endColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1).cgColor
gradient.colors = [startColor, endColor]
newspaperview.layer.insertSublayer(gradient, at: 0)
newspaperImage.addSubview(newspaperview)
newspaperImage.bringSubviewToFront(newspaperview)
}
override func viewDidLoad() {
super.viewDidLoad()
imageGradient()
}
After running, I find it doesn't work at all. 运行后,我发现它根本不起作用。 Where's the problem? 哪里出问题了?
First lets start with UIColor(red:green:blue:alpha)
expects the parameters to be normalised values of 0-1. 首先让我们从UIColor(red:green:blue:alpha)
期望参数的标准化值为0-1。
So... 所以...
let startColor = UIColor(red: 30, green: 113, blue: 79, alpha: 0).cgColor
should be 应该
let startColor = UIColor(red: 30/255, green: 113/255, blue: 79/255, alpha: 0).cgColor
Next, I took your basic code and dumped into Playground 接下来,我拿了您的基本代码并转交给Playground
let image = UIImage(named: "Miho_Small.png")
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
imageView.contentMode = .scaleAspectFit
imageView.image = image
let gradient = CAGradientLayer()
gradient.frame = imageView.bounds
let startColor = UIColor(red: 30/255, green: 113/255, blue: 79/255, alpha: 0).cgColor
let endColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1).cgColor
gradient.colors = [startColor, endColor]
imageView.layer.insertSublayer(gradient, at: 0)
imageView
And it generated... 它产生了...
Okay, that's not what I was expecting, but it's not entirely unsurprising. 好的,这不是我所期望的,但这并不完全令人惊讶。 The CALayer
is been painted over the top of the image, because the image is been painted by the UIView
's draw
function. CALayer
被绘制在图像的顶部,因为该图像是通过UIView
的draw
函数draw
。
Okay, so how can we fix it? 好吧,那我们该如何解决呢? With out going to the extend of making a new images and painting the gradient and image into it, you could make use of a "background" UIView
, onto which the layer and UIImageView
are applied... 在不进行制作新图像并将渐变和图像绘制到其中的扩展过程中,您可以使用“背景” UIView
,在该UIView
上应用图层和UIImageView
。
let image = UIImage(named: "Miho_Small.png")
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
imageView.contentMode = .scaleAspectFit
imageView.image = image
imageView.backgroundColor = nil
let backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
let gradient = CAGradientLayer()
gradient.frame = backgroundView.bounds
let startColor = UIColor(red: 30/255, green: 113/255, blue: 79/255, alpha: 0).cgColor
let endColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1).cgColor
gradient.colors = [startColor, endColor]
backgroundView.layer.insertSublayer(gradient, at: 0)
backgroundView.addSubview(imageView)
backgroundView
which generates... 会产生...
And, that's probably more along the lines of what you're trying to achieve...at a guess 而且,可能更像是您要实现的目标...猜测
:(, the two views can not be overlapped :(,两个视图不能重叠
I don't "overlap", so to speak, I add the UIImageView
onto the backgroundView
, which contains the CALayer
. 我不会“重叠”,可以这么说,我将UIImageView
添加到包含CALayer
的backgroundView
。 Remember, the view's frame
is relative to it's parent's coordinate space. 请记住,视图的frame
是相对于其父级的坐标空间的。
In almost all cases, I prefer to use auto layout, and I prefer to use story boards, but those are difficult to make int an answer, so I've done it by hand for this example... 在几乎所有情况下,我都喜欢使用自动布局,并且我喜欢使用情节提要,但是这些很难使int成为答案,因此在此示例中我已经手工完成了...
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let image = UIImage(named: "Miho_Small.png")
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 250, height: 250))
imageView.contentMode = .scaleAspectFit
imageView.image = image
imageView.backgroundColor = nil
let backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: 250, height: 250))
backgroundView.translatesAutoresizingMaskIntoConstraints = false
let gradient = CAGradientLayer()
gradient.frame = backgroundView.bounds
let startColor = UIColor(red: 30/255, green: 113/255, blue: 79/255, alpha: 0).cgColor
let endColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1).cgColor
gradient.colors = [startColor, endColor]
backgroundView.layer.insertSublayer(gradient, at: 0)
backgroundView.addSubview(imageView)
view.addSubview(backgroundView)
imageView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor).isActive = true
imageView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: backgroundView.topAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor).isActive = true
backgroundView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
backgroundView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
backgroundView.addConstraint(NSLayoutConstraint(item: backgroundView,
attribute: .width,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1.0,
constant: 250))
backgroundView.addConstraint(NSLayoutConstraint(item: backgroundView,
attribute: .width,
relatedBy: .equal,
toItem: backgroundView,
attribute: .height,
multiplier: 1.0,
constant: 0))
}
}
For what it's worth, you can checkout the project I used to test the code from GitHub - TestCALayerGradientAndImageOverlay 对于它的价值,您可以从GitHub检出我用来测试代码的项目-TestCALayerGradientAndImageOverlay
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.