Search code examples
iosswiftuiviewcalayer

UIView.mask set the color


I have a 50px square UIView that I'm setting as the mask for my superview.

let squareView = UIView(frame...)

self.view.mask = squareView

The result is a 50px square transparent area, but the color of the masked area around it is always white. How do I change the color of the masked area around my transparent square to black?

 _______________
|               |    
|    <-------------- Masked area that I would like to change the color of
|               |
|      000000   |
|      000000 <-------- squareView: becomes transparent as expected
|      000000   |
|      000000   |
|               |
|               |
|               |
|_______________|

Solution

  • This is a code snippet that demonstrates the effect you want, I think. You should be able to paste it into a new "single view" iOS project as the viewDidLoad() method of the view controller that the Xcode template creates.

    I needed some way to set the content of the mask view without creating a subclass of UIView (because I'm lazy) so my sample creates an image (whose alpha channel is 1.0 for the most part with a 100x100 square of clear alpha channel). I set this to be the content of the mask view.

    The timer at the end just cycles through a bunch of colors for the outer view because... it's fun.

    override func viewDidLoad() {
          super.viewDidLoad()
          self.view.backgroundColor = UIColor.blue
    
          let overallView = UIView(frame: CGRect(x:100, y:100, width:300, height:300))
          overallView.backgroundColor = UIColor.green
    
          // Draw a graphics with a mostly solid alpha channel
          // and a square of "clear" alpha in there.
          UIGraphicsBeginImageContext(overallView.bounds.size)
          let cgContext = UIGraphicsGetCurrentContext()
          cgContext?.setFillColor(UIColor.white.cgColor)
          cgContext?.fill(overallView.bounds)
          cgContext?.clear(CGRect(x:100, y:100, width: 100, height: 100))
          let maskImage = UIGraphicsGetImageFromCurrentImageContext()
          UIGraphicsEndImageContext()
    
          // Set the content of the mask view so that it uses our
          // alpha channel image
          let maskView = UIView(frame: overallView.bounds)
          maskView.layer.contents = maskImage?.cgImage
          overallView.mask = maskView
    
          self.view.addSubview(overallView)
    
          var hue = CGFloat(0)
          Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true) {
              (_) in
              let color = UIColor(hue: hue, saturation: 1.0, brightness: 1.0, alpha: 1.0)
              hue = hue + (1.0/20);
              if hue >= 1.0 { hue = 0 }
    
              overallView.backgroundColor = color
          }
      }