标签的反向图层蒙版
Reverse layer mask for label
如何反转标签的遮罩层?我有一个 textLabel
,我将其用作包含任意图像的 imageView
的掩码,如下所示:
let image = UIImage(named: "someImage")
let imageView = UIImageView(image: image!)
let textLabel = UILabel()
textLabel.frame = imageView.bounds
textLabel.text = "Some text"
imageView.layer.mask = textLabel.layer
imageView.layer.masksToBounds = true
以上内容使 textLabel
中的文本具有与 How to mask the layer of a view by the content of another view? 中相同的 imageView
字体颜色。
我如何反转它以便删除textLabel
imageView
中的文本?
创建 UILabel
的子类:
class InvertedMaskLabel: UILabel {
override func drawTextInRect(rect: CGRect) {
guard let gc = UIGraphicsGetCurrentContext() else { return }
CGContextSaveGState(gc)
UIColor.whiteColor().setFill()
UIRectFill(rect)
CGContextSetBlendMode(gc, .Clear)
super.drawTextInRect(rect)
CGContextRestoreGState(gc)
}
}
这个子类用不透明的颜色填充它的边界(在这个例子中是白色,但只有 alpha 通道很重要)。然后它使用 Clear
混合模式绘制文本,它只是将上下文的所有通道设置回 0,包括 alpha 通道。
游乐场演示:
let root = UIView(frame: CGRectMake(0, 0, 400, 400))
root.backgroundColor = .blueColor()
XCPlaygroundPage.currentPage.liveView = root
let image = UIImage(named: "Kaz-256.jpg")
let imageView = UIImageView(image: image)
root.addSubview(imageView)
let label = InvertedMaskLabel()
label.text = "Label"
label.frame = imageView.bounds
label.font = .systemFontOfSize(40)
imageView.maskView = label
结果:
由于我最近需要实现它并且语法发生了一些变化,这里有一个 Swift 4.x 版本 @RobMayoff 的优秀答案。 Demo/GitHub 回购 Swift 游乐场位于 here。
(如果您对此投赞成票,请也为他的原始答案投赞成票:))
演示该技术的游乐场。 InvertedMaskLabel
中的方法 drawRect
有秘诀。
import UIKit
import PlaygroundSupport
// As per
class InvertedMaskLabel: UILabel {
override func drawText(in rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
context.saveGState()
UIColor.white.setFill()
UIRectFill(rect) // fill bounds w/opaque color
context.setBlendMode(.clear)
super.drawText(in: rect) // draw text using clear blend mode, ie: set *all* channels to 0
context.restoreGState()
}
}
class TestView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .green
let image = UIImage(named: "tr")
let imageView = UIImageView(image: image)
imageview.frame = bounds
addSubview(imageView)
let label = InvertedMaskLabel()
label.text = "Teddy"
label.frame = imageView.bounds
label.font = UIFont.systemFont(ofSize: 30)
imageView.mask = label
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
let testView = TestView(frame: CGRect(x: 0, y: 0, width: 400, height: 500))
PlaygroundPage.current.liveView = testView
如何反转标签的遮罩层?我有一个 textLabel
,我将其用作包含任意图像的 imageView
的掩码,如下所示:
let image = UIImage(named: "someImage")
let imageView = UIImageView(image: image!)
let textLabel = UILabel()
textLabel.frame = imageView.bounds
textLabel.text = "Some text"
imageView.layer.mask = textLabel.layer
imageView.layer.masksToBounds = true
以上内容使 textLabel
中的文本具有与 How to mask the layer of a view by the content of another view? 中相同的 imageView
字体颜色。
我如何反转它以便删除textLabel
imageView
中的文本?
创建 UILabel
的子类:
class InvertedMaskLabel: UILabel {
override func drawTextInRect(rect: CGRect) {
guard let gc = UIGraphicsGetCurrentContext() else { return }
CGContextSaveGState(gc)
UIColor.whiteColor().setFill()
UIRectFill(rect)
CGContextSetBlendMode(gc, .Clear)
super.drawTextInRect(rect)
CGContextRestoreGState(gc)
}
}
这个子类用不透明的颜色填充它的边界(在这个例子中是白色,但只有 alpha 通道很重要)。然后它使用 Clear
混合模式绘制文本,它只是将上下文的所有通道设置回 0,包括 alpha 通道。
游乐场演示:
let root = UIView(frame: CGRectMake(0, 0, 400, 400))
root.backgroundColor = .blueColor()
XCPlaygroundPage.currentPage.liveView = root
let image = UIImage(named: "Kaz-256.jpg")
let imageView = UIImageView(image: image)
root.addSubview(imageView)
let label = InvertedMaskLabel()
label.text = "Label"
label.frame = imageView.bounds
label.font = .systemFontOfSize(40)
imageView.maskView = label
结果:
由于我最近需要实现它并且语法发生了一些变化,这里有一个 Swift 4.x 版本 @RobMayoff 的优秀答案。 Demo/GitHub 回购 Swift 游乐场位于 here。
(如果您对此投赞成票,请也为他的原始答案投赞成票:))
演示该技术的游乐场。 InvertedMaskLabel
中的方法 drawRect
有秘诀。
import UIKit
import PlaygroundSupport
// As per
class InvertedMaskLabel: UILabel {
override func drawText(in rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
context.saveGState()
UIColor.white.setFill()
UIRectFill(rect) // fill bounds w/opaque color
context.setBlendMode(.clear)
super.drawText(in: rect) // draw text using clear blend mode, ie: set *all* channels to 0
context.restoreGState()
}
}
class TestView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .green
let image = UIImage(named: "tr")
let imageView = UIImageView(image: image)
imageview.frame = bounds
addSubview(imageView)
let label = InvertedMaskLabel()
label.text = "Teddy"
label.frame = imageView.bounds
label.font = UIFont.systemFont(ofSize: 30)
imageView.mask = label
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
let testView = TestView(frame: CGRect(x: 0, y: 0, width: 400, height: 500))
PlaygroundPage.current.liveView = testView