2017-10-21 239 views
1

所以我有一个UILabel正在绘制在梯度图像(即UIImageView)的顶部。它看起来有几分像这样:如何在Swift中绘制具有不同混合模式的UILabel(__rect:CGRect)

enter image description here

我试图更改UILabeldraw(_ rect: CGRect)函数图形上下文的blendMode,以便它绘制标签,但是兑入了softLight混合模式的背景。

这是我希望它看起来像:

enter image description here

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

override func draw(_ rect: CGRect) { 
    // Drawing code 
    if let context = UIGraphicsGetCurrentContext() { 
     context.setBlendMode(.softLight) 
     self.textColor.set() 
     self.drawText(in: rect) 
    } 
} 

此代码只是使顶部的图片,而不是混合版本。这并不是我所尝试过的,我尝试了很多其他的东西,但我不明白CGContextdraw函数。

对于SO的大多数答案都在旧的Objective-C中,并且被弃用/破坏或者很快并且太复杂(例如使用Metal)。我只想在上下文中绘制文本,并将上下文的混合模式设置为柔和光线。必须有一个简单的方法!

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

回答

1

您不能以这种方式混合视图;他们有单独解决的层次结构。将对象上的渐变和文字移动并混合(或在同一视图中手工绘制)。例如:

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

enter image description here

+0

谢谢你的回答!你似乎是唯一理解并能够给我想要的东西的人。不幸的是,我的标签正在移动,所以我希望它在每个时间步更新其“混合色”。有没有办法做到这一点? – QuantumHoneybees

+0

这只是动画。你需要一些属性来指示文本的位置。使用'animate(withDuration:animations:)'来修改该属性,并为该属性添加一个'didSet'以在其更改时调用'setNeedsDisplay'。 (原则上有更多的高性能方法,但它们更复杂,所以除非遇到严重的性能问题,否则不要担心。即使您轻松使用Core Graphics和Core Animation,也已经非常善于优化这些内容路线和最天真的优化尝试只是打击系统,并使其变得更糟糕。) –

+0

请注意,您可以使用“CALayer”而不是“UIView”来完成此操作,但是可以将“CALayer”的自定义属性动画化比听起来有点棘手。这并不难,但它很微妙,我通常不会推荐给人们,除非他们需要它。 –

0

因此,如果您的文字确实是一个标签,您可以尝试改变不透明度,就像普通标签一样。我假设你熟悉为标签设置一个alpha。请从下面一个例子用于设置阿尔法标签:

label.textColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.25) 

请给我一个提示,如果它不是一个标签 - 那么它应该是更加复杂。

+0

它是一种标签,但我不希望改变的不透明度,我想混合模式具体更改为柔和的光线(或其它模式)。 – QuantumHoneybees

相关问题