Mask UIView / UIImageView to cut transparent text

How can I mask a UIView or UIImageView so that the text is cut out of it?

I walked a lot, and it seems that many people fought the same way. Most annoying, I always tried to invert the alpha of the picture to get the result.

I want to look like this:

enter image description here

+5
source share
2 answers

The main problem I encountered is my understanding. Instead of making a color image and trying to make a transparent hole in it, we can simply fold it the other way around. So we have a colored background in the back, and then an image in front that has a mask to display only the text part. And actually, it's pretty simple if you are using iOS 8+ using the maskView UIView property.

So it might look something like this:

let coloredBackground = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 100)) coloredBackground.backgroundColor = UIColor.greenColor() let imageView = UIImageView(frame: coloredBackground.bounds) imageView.image = UIImage(named: "myImage") coloredBackground.addSubview(imageView) let label = UILabel(frame: coloredBackground.bounds) label.text = "stackoverflow" coloredBackground.addSubview(label) imageView.maskView = label 
+3
source

This is a custom mask label.

 import UIKit final class MaskLabel: UILabel { // MARK: - IBInspectoable @IBInspectable var cornerRadius: CGFloat { get { return self.layer.cornerRadius } set { self.layer.cornerRadius = newValue } } @IBInspectable var borderWidth: CGFloat { get { return self.layer.cornerRadius } set { self.layer.borderWidth = newValue } } @IBInspectable var borderColor: UIColor { get { return UIColor(cgColor: self.layer.borderColor ?? UIColor.clear.cgColor) } set { self.layer.borderColor = newValue.cgColor } } @IBInspectable var insetTop: CGFloat { get { return self.textInsets.top } set { self.textInsets.top = newValue } } @IBInspectable var insetLeft: CGFloat { get { return self.textInsets.left } set { self.textInsets.left = newValue } } @IBInspectable var insetBottom: CGFloat { get { return self.textInsets.bottom } set { self.textInsets.bottom = newValue } } @IBInspectable var insetRight: CGFloat { get { return self.textInsets.right } set { self.textInsets.right = newValue } } // MARK: - Value // MARK: Public private var textInsets = UIEdgeInsets.zero private var originalBackgroundColor: UIColor? = nil // MARK: - Initializer required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setLabelUI() } override init(frame: CGRect) { super.init(frame: frame) setLabelUI() } override func prepareForInterfaceBuilder() { setLabelUI() } // MARK: - Draw override func drawText(in rect: CGRect) { super.drawText(in: UIEdgeInsetsInsetRect(rect, textInsets)) guard let context = UIGraphicsGetCurrentContext() else { return } context.saveGState() context.setBlendMode(.clear) originalBackgroundColor?.setFill() UIRectFill(rect) super.drawText(in: rect) context.restoreGState() } // MARK: - Function // MARK: Private private func setLabelUI() { // cache (Before masking the label, the background color must be clear. So we have to cache it) originalBackgroundColor = backgroundColor backgroundColor = .clear layer.cornerRadius = cornerRadius layer.borderWidth = borderWidth layer.borderColor = borderColor.cgColor } } 

enter image description here enter image description here

This is the result. enter image description here

+1
source

All Articles