Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a UIView with a transparent circle inside (in swift)?

I want to create a view that looks like this: Goal View

I figure what I need is a uiview with some sort of mask, I can make a mask in the shape of a circle using a UIBezierpath, however I cannot invert this makes so that it masks everything but the circle. I need this to be a mask of a view and not a fill layer because the view that I intend to mask has a UIBlurEffect on it. The end goal is to animate this UIView overtop of my existing views to provide instruction.

Please note that I am using swift. Is there away to do this? If so, how?

like image 705
chanceofthat Avatar asked Feb 11 '15 07:02

chanceofthat


People also ask

How do you make a triangle view in Swift?

Swift 2: class ViewController: UIViewController { override func viewDidLoad() { super. viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let triangle = TriangleView(frame: CGRectMake(10, 20, 25, 30)) triangle.


2 Answers

You can use this function to create what you need.

func createOverlay(frame : CGRect) {     let overlayView = UIView(frame: frame)     overlayView.alpha = 0.6     overlayView.backgroundColor = UIColor.blackColor()     self.view.addSubview(overlayView)      let maskLayer = CAShapeLayer()      // Create a path with the rectangle in it.     var path = CGPathCreateMutable()      let radius : CGFloat = 50.0     let xOffset : CGFloat = 10     let yOffset : CGFloat = 10      CGPathAddArc(path, nil, overlayView.frame.width - radius/2 - xOffset, yOffset, radius, 0.0, 2 * 3.14, false)     CGPathAddRect(path, nil, CGRectMake(0, 0, overlayView.frame.width, overlayView.frame.height))       maskLayer.backgroundColor = UIColor.blackColor().CGColor      maskLayer.path = path;     maskLayer.fillRule = kCAFillRuleEvenOdd      // Release the path since it's not covered by ARC.     overlayView.layer.mask = maskLayer     overlayView.clipsToBounds = true } 

Adjust the radius and xOffset and yOffset to change the radius and position of the circle.

like image 39
rakeshbs Avatar answered Oct 06 '22 05:10

rakeshbs


Updated again for Swift 4 & removed a few items to make the code tighter.

Please note that maskLayer.fillRule is set differently between Swift 4 and Swift 4.2.

func createOverlay(frame: CGRect,                    xOffset: CGFloat,                    yOffset: CGFloat,                    radius: CGFloat) -> UIView {     // Step 1     let overlayView = UIView(frame: frame)     overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.6)     // Step 2     let path = CGMutablePath()     path.addArc(center: CGPoint(x: xOffset, y: yOffset),                 radius: radius,                 startAngle: 0.0,                 endAngle: 2.0 * .pi,                 clockwise: false)     path.addRect(CGRect(origin: .zero, size: overlayView.frame.size))     // Step 3     let maskLayer = CAShapeLayer()     maskLayer.backgroundColor = UIColor.black.cgColor     maskLayer.path = path     // For Swift 4.0     maskLayer.fillRule = kCAFillRuleEvenOdd     // For Swift 4.2     maskLayer.fillRule = .evenOdd     // Step 4     overlayView.layer.mask = maskLayer     overlayView.clipsToBounds = true      return overlayView } 

A rough breakdown on what is happening:

  1. Create a view sized to the specified frame, with a black background set to 60% opacity
  2. Create the path for drawing the circle using the provided starting point and radius
  3. Create the mask for the area to remove
  4. Apply the mask & clip to bounds

The following code snippet will call this and place a circle in the middle of the screen with radius of 50:

let overlay = createOverlay(frame: view.frame,                             xOffset: view.frame.midX,                             yOffset: view.frame.midY,                             radius: 50.0) view.addSubview(overlay) 

Which looks like this: enter image description here

like image 150
CodeBender Avatar answered Oct 06 '22 03:10

CodeBender