I want to achieve the following focused UI. It is basically the guideline tutorial view for my users.
The background is my main view controller with a bunch of real functional views and I put a view with 50% transparency on black on top of it to achieve the focused UI but it's far away from what I am trying to achieve. Any suggestion would be highly appreciated.
Code:
func createOverlay(frame: CGRect,
xOffset: CGFloat,
yOffset: CGFloat,
radius: CGFloat) -> UIView {
// Step 1
let overlayView = UIView(frame: frame)
overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
// 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 = CAShapeLayerFillRule.evenOdd
// For Swift 4.2
maskLayer.fillRule = .evenOdd
// Step 4
overlayView.layer.mask = maskLayer
overlayView.clipsToBounds = true
return overlayView
}


We can do this by using an "inverted" shadow-path on the overlay view's layer. That will give us a "feathered-edge" oval.
Here is an example view class:
and an example controller. We'll add 6 colored rectangles to use as a "background" and a
UILabelto "focus" on:Each tap anywhere will either fade-in or fade-out the focus view: