So I have a UILabel
that is being drawn on top of a gradient image (that is a UIImageView
). It looks sorta like this:
I'm trying to change the blendMode
of the graphics context in the UILabel
's draw(_ rect: CGRect)
function so that it draws the label but blended with the background with a softLight
blending mode.
Here is what I want it to look like:
Here is the code I have in the draw(_ rect: CGRect)
function:
override func draw(_ rect: CGRect) {
// Drawing code
if let context = UIGraphicsGetCurrentContext() {
context.setBlendMode(.softLight)
self.textColor.set()
self.drawText(in: rect)
}
}
This code just renders the top picture and not the blended version. This is not all that I've tried, I've tried so much other things but I just don't understand CGContext
's and the draw
function in particular.
Most answers on SO are either in old objective-c and are deprecated/broken or swift and too complicated (use Metal for example). I just want to draw the text in the context I have and set the context's blending mode to soft light. There has to be an easy way!
Any help on how to fix this would be appreciated. Thanks!
You can't blend views this way; they have separate layer hierarchies that are resolved independently. Move the gradient and text on CALayer
objects and blend those (or draw them by hand inside the same view). For example:
class MyView: UIView {
let gradientLayer: CAGradientLayer = {
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.red.cgColor,
UIColor.blue.cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)
return gradientLayer
}()
let textLayer: CATextLayer = {
let textLayer = CATextLayer()
let astring = NSAttributedString(string: "Text Example",
attributes: [.font: UIFont(name: "MarkerFelt-Wide", size: 60)!])
textLayer.string = astring
textLayer.alignmentMode = kCAAlignmentCenter
textLayer.bounds = astring.boundingRect(with: CGSize(width: .max, height: .max),
options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil)
return textLayer
}()
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
gradientLayer.bounds = bounds
gradientLayer.render(in: context)
context.saveGState()
context.setBlendMode(.softLight)
context.translateBy(x: center.x - textLayer.bounds.width / 2,
y: center.y - textLayer.bounds.height / 2)
textLayer.position = center
textLayer.render(in: context)
context.restoreGState()
}
}
}
So in case your text is really a label you could try it with changing the opacity like for normal labels. I assume you're familiar with setting an alpha to a label. Please find below one example for setting an alpha for a label:
label.textColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.25)
Please give me a hint, if it's not a label - then it should be more complicated.
来源:https://stackoverflow.com/questions/46865660/how-to-draw-a-uilabel-with-a-different-blend-mode-in-draw-rect-cgrect-in-swi