ZbadhabitZ
ZbadhabitZ

Reputation: 2913

Masking A UIView With UILabel Using AutoLayout

I am working on a project that would result in this desired effect:

enter image description here

I am successfully drawing my circle using the following code:

let circle = CircleView()
circle.translatesAutoresizingMaskIntoConstraints = false
circle.backgroundColor = UIColor.clear
self.addSubview(circle)

    // Setup constraints
    circle.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
    circle.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
    circle.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.6).isActive = true
    circle.heightAnchor.constraint(equalTo: circle.widthAnchor, multiplier: 1.0/1.0).isActive = true

For reference, this is my CircleView class:

class CircleView: UIView {

    override func draw(_ rect: CGRect) {

        // Set the path
        let path = UIBezierPath(ovalIn: rect)

        // Set the fill color
        UIColor.black.setFill()

        // Fill
        path.fill()
    }
}

Subsequently, I am then creating my UILabel, as such:

let myLabel = UILabel()
myLabel.translatesAutoresizingMaskIntoConstraints = false
myLabel.text = "HELLO"
myLabel.textColor = UIColor.white
circle.addSubview(myLabel)

    // Setup constraints
    myLabel.centerXAnchor.constraint(equalTo: circle.centerXAnchor).isActive = true
    myLabel.centerYAnchor.constraint(equalTo: circle.centerYAnchor).isActive = true

I have attempted to mask my circle by using:

circle.mask = myLabel

This, however, results in the opposite effect I am after (my text is not a cut-out in the UIView, but rather, my text is now black). Where might I be going wrong to accomplish this effect?

Upvotes: 0

Views: 948

Answers (1)

James Woodrow
James Woodrow

Reputation: 385

Masks work in an opposite fashion, when the color on your mask is not transparent then it will show the content in that pixels position and when the pixels are transparent then it will hide the content.

Since you can't achieve this using UILabel you need to use something else as a mask, such as a CALayer.

If you lookup "UILabel see through text" you should find results similar to this which basically also applies to you (with some changes).

Instantiate your CircleView, then instantiate a CATextLayer and use this as a mask for your UIView

Upvotes: 2

Related Questions