I want to create a view that looks like this:
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?
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.
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.
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:
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With