如何在 Swift 中的 draw(_ rect: CGRect) 中使用不同的混合模式绘制 UILabel
How to draw a UILabel with a different blend mode in draw(_ rect: CGRect) in Swift
所以我有一个 UILabel
被绘制在渐变图像的顶部(即 UIImageView
)。它看起来像这样:
我正在尝试更改 UILabel
的 draw(_ rect: CGRect)
函数中图形上下文的 blendMode
,以便它绘制标签但与背景混合 softLight
混合模式。
这是我想要的样子:
这是我在 draw(_ rect: CGRect)
函数中的代码:
override func draw(_ rect: CGRect) {
// Drawing code
if let context = UIGraphicsGetCurrentContext() {
context.setBlendMode(.softLight)
self.textColor.set()
self.drawText(in: rect)
}
}
此代码只渲染顶部图片而不是混合版本。这不是我尝试过的全部,我已经尝试了很多其他的东西,但我就是不理解 CGContext
,尤其是 draw
函数。
关于 SO 的大多数答案要么是旧的 objective-c 要么是 deprecated/broken 或 swift 并且太复杂了(例如使用 Metal)。我只想在我拥有的上下文中绘制文本,并将上下文的混合模式设置为柔光。必须有一个简单的方法!
如能提供解决此问题的任何帮助,我们将不胜感激。谢谢!
因此,如果您的文本确实是一个标签,您可以尝试像普通标签一样更改不透明度。我假设您熟悉为标签设置 alpha。请在下面找到一个为标签设置 alpha 的示例:
label.textColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.25)
请指点一下,如果不是标签,应该更复杂一些。
您不能以这种方式混合视图;它们具有独立解析的单独层层次结构。移动 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(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()
}
}
}
所以我有一个 UILabel
被绘制在渐变图像的顶部(即 UIImageView
)。它看起来像这样:
我正在尝试更改 UILabel
的 draw(_ rect: CGRect)
函数中图形上下文的 blendMode
,以便它绘制标签但与背景混合 softLight
混合模式。
这是我想要的样子:
这是我在 draw(_ rect: CGRect)
函数中的代码:
override func draw(_ rect: CGRect) {
// Drawing code
if let context = UIGraphicsGetCurrentContext() {
context.setBlendMode(.softLight)
self.textColor.set()
self.drawText(in: rect)
}
}
此代码只渲染顶部图片而不是混合版本。这不是我尝试过的全部,我已经尝试了很多其他的东西,但我就是不理解 CGContext
,尤其是 draw
函数。
关于 SO 的大多数答案要么是旧的 objective-c 要么是 deprecated/broken 或 swift 并且太复杂了(例如使用 Metal)。我只想在我拥有的上下文中绘制文本,并将上下文的混合模式设置为柔光。必须有一个简单的方法!
如能提供解决此问题的任何帮助,我们将不胜感激。谢谢!
因此,如果您的文本确实是一个标签,您可以尝试像普通标签一样更改不透明度。我假设您熟悉为标签设置 alpha。请在下面找到一个为标签设置 alpha 的示例:
label.textColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.25)
请指点一下,如果不是标签,应该更复杂一些。
您不能以这种方式混合视图;它们具有独立解析的单独层层次结构。移动 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(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()
}
}
}