3

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   |
|               |
|               |
|               |
|_______________|
bgolson
  • 3,460
  • 5
  • 24
  • 41
  • Try setting the background color of the view's layer to black `self.view.layer.backgroundColor = UIColor.black.CGColor` (typed into comment... may need some tweaking to compile) – Scott Thompson May 04 '17 at 17:10
  • this might help: http://stackoverflow.com/questions/29585943/how-do-i-successfully-set-a-maskview-to-a-uiview – janusfidel May 04 '17 at 17:19
  • @ScottThompson Thanks, but setting the background color of the main view had no effect on the color of the mask applied to it. Setting the background color on the mask view also has no effect. – bgolson May 04 '17 at 20:42
  • @janusbalatbat Thanks, but I couldn't find anything in this post related to setting the background color of the masked area. – bgolson May 04 '17 at 20:42
  • The only component of the mask view that will be used is the alpha channel. I suggested you set the background color of the view's layer, not the view's background color. A subtle but important distinction. Perhaps if you showed a bit more of your code and perhaps a picture of the undesirable state we could help more. – Scott Thompson May 05 '17 at 02:38
  • Thanks for following up Scott, I added a drawing and a little more code. Changing the layer background color also did not effect the color of the mask, only the background color of the view underneath. – bgolson May 05 '17 at 02:55

1 Answers1

5

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
      }
  }
Scott Thompson
  • 22,629
  • 4
  • 32
  • 34