如何在Swift中的draw(_ rect:CGRect)中绘制具有不同混合模式的UILabel [英] How to draw a UILabel with a different blend mode in draw(_ rect: CGRect) in Swift

查看:595
本文介绍了如何在Swift中的draw(_ rect:CGRect)中绘制具有不同混合模式的UILabel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个 UILabel 绘制在渐变图像的顶部(即 UIImageView ) 。看起来有点像这样:





这是我在 draw(_ rect:CGRect)函数中拥有的代码:

 重写func draw(_ rect:CGRect){
//绘制代码
如果let context = UIGraphicsGetCurrentContext(){
context.setBlendMode (.softLight)
self.textColor.set()
self.drawText(in rect)
}
}

此代码仅渲染顶部图片,而不渲染混合版本。这不是我尝试过的全部,我尝试过很多其他的事情,但是我只是不理解 CGContext draw



大多数关于SO的答案要么在旧的Objective-c中被弃用/损坏,要么迅速而又过于复杂(请使用Metal例如)。我只想在已有的上下文中绘制文本,并将上下文的混合模式设置为柔和的光线。必须有一种简单的方法!



任何有关如何解决此问题的帮助将不胜感激。谢谢!

解决方案

您无法以这种方式混合视图;它们具有独立解决的单独的层层次结构。在 CALayer 对象上移动渐变和文本并将其混合(或在同一视图内手工绘制)。例如:

  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(字符串:文本示例,
属性:[。font:UIFont(名称: MarkerFelt-Wide,大小:60)!])
textLayer.string = astring
textLayer.alignmentMode = kCAAlignmentCenter
textLayer.bounds = astring.boundingRect(with:CGSize(width:.max,height:.max),
选项:[.usesLineFragmentOrigin,.usesF ontLeading],上下文:无)
return textLayer
}()

覆盖func draw(_ rect:CGRect){
if let context = UIGraphicsGetCurrentContext(){
gradientLayer.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 =中心
textLayer.render(在上下文中)
context.restoreGState()
}
}
}


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()
        }
    }
}

这篇关于如何在Swift中的draw(_ rect:CGRect)中绘制具有不同混合模式的UILabel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆