Reputation: 16180
How to draw View like this.
After research I got context.fillRects
method can be used. But how to find the exact rects for this.
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(UIColor.red.cgColor)
context?.setAlpha(0.5)
context?.fill([<#T##rects: [CGRect]##[CGRect]#>])
How to achieve this result?
Background: Blue.
Overlay(Purple): 50% opacity that contains square hole in the center
Upvotes: 0
Views: 542
Reputation: 16180
I just ended up with this.
Code:
createHoleOnView()
let blurView = createBlurEffect(style: style)
self.addSubview(blurView)
Method Create Hole:
private func createHoleOnView() {
let maskView = UIView(frame: self.frame)
maskView.clipsToBounds = true;
maskView.backgroundColor = UIColor.clear
func holeRect() -> CGRect {
var holeRect = CGRect(x: 0, y: 0, width: scanViewSize.rawValue.width, height: scanViewSize.rawValue.height)
let midX = holeRect.midX
let midY = holeRect.midY
holeRect.origin.x = maskView.frame.midX - midX
holeRect.origin.y = maskView.frame.midY - midY
self.holeRect = holeRect
return holeRect
}
let outerbezierPath = UIBezierPath.init(roundedRect: self.bounds, cornerRadius: 0)
let holePath = UIBezierPath(roundedRect: holeRect(), cornerRadius: holeCornerRadius)
outerbezierPath.append(holePath)
outerbezierPath.usesEvenOddFillRule = true
let hollowedLayer = CAShapeLayer()
hollowedLayer.fillRule = kCAFillRuleEvenOdd
hollowedLayer.fillColor = outerColor.cgColor
hollowedLayer.path = outerbezierPath.cgPath
if self.holeStyle == .none {
hollowedLayer.opacity = 0.8
}
maskView.layer.addSublayer(hollowedLayer)
switch self.holeStyle {
case .none:
self.addSubview(maskView)
break
case .blur(_):
self.mask = maskView;
break
}
}
UIView's Extension function for Create Blur:
internal func createBlurEffect(style: UIBlurEffectStyle = .extraLight) -> UIView {
let blurEffect = UIBlurEffect(style: style)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.bounds
return blurEffectView
}
Upvotes: 0
Reputation: 1809
First create your view and then draw everything with two UIBezierPaths: one is describing the inside rect (the hole) and the other one runs along the borders on your screen (externalPath). This way of drawing ensures that the blue rect in the middle is a true hole and not drawn on top of the purple view.
let holeWidth: CGFloat = 200
let hollowedView = UIView(frame: view.frame)
hollowedView.backgroundColor = UIColor.clear
//Initialise the layer
let hollowedLayer = CAShapeLayer()
//Draw your two paths and append one to the other
let holePath = UIBezierPath(rect: CGRect(origin: CGPoint(x: (view.frame.width - holeWidth) / 2, y: (view.frame.height - holeWidth) / 2), size: CGSize(width: holeWidth, height: holeWidth)))
let externalPath = UIBezierPath(rect: hollowedView.frame).reversing()
holePath.append(externalPath)
holePath.usesEvenOddFillRule = true
//Assign your path to the path property of your layer
hollowedLayer.path = holePath.cgPath
hollowedLayer.fillColor = UIColor.purple.cgColor
hollowedLayer.opacity = 0.5
//Add your hollowedLayer to the layer of your hollowedView
hollowedView.layer.addSublayer(hollowedLayer)
view.addSubview(hollowedView)
Upvotes: 2
Reputation: 304
Create a custom UIView with background color blue.
class CustomView: UIView {
// Try adding a rect and fill color.
override func draw(_ rect: CGRect) {
let ctx = UIGraphicsGetCurrentContext()
ctx!.beginPath()
//Choose the size based on the size required.
ctx?.addRect(CGRect(x: 20, y: 20, width: rect.maxX - 40, height: rect.maxY - 40))
ctx!.closePath()
ctx?.setFillColor(UIColor.red.cgColor)
ctx!.fillPath()
}
}
Upvotes: 0