I want to draw a transparent arc connecting two corners of the rect so that I can see what is behind the view through the arc.
I can able to draw the arc using the following code
override func draw(_ rect: CGRect) {
// Drawing code
let arcHeight: CGFloat = 10
let arcColor = UIColor.blue
let arcRect = CGRect(x: 0, y: rect.height - arcHeight, width: rect.width, height: arcHeight)
let arcRadius = (arcHeight / 2) + (pow(arcRect.width, 2) / (8 * arcHeight))
let arcCenter = CGPoint(x: arcRect.origin.x + (arcRect.width / 2), y: arcRect.origin.y + arcRadius)
let angle = acos(arcRect.width / (2 * arcRadius))
let startAngle = radians(180) + angle
let endAngle = radians(360) - angle
let path = UIBezierPath(arcCenter: arcCenter, radius: arcRadius / 2, startAngle: startAngle, endAngle: endAngle, clockwise: true)
path.lineWidth = arcRadius
arcColor.setStroke()
path.stroke()
}
private func radians(_ degrees: CGFloat) -> CGFloat {
return degrees * CGFloat(M_PI) / 180
}
So to make the arc transparent I need to fill the remaining part of the rect excluding the arc for that I tried the below code,
let fullPath = UIBezierPath(rect: bounds)
fullPath.append(path)
fullPath.usesEvenOddFillRule = true
fullPath.addClip()
arcColor.setFill()
fullPath.fill()
But I cannot achieve what I expect. Kindly guide me how to fill the rect with color excluding the arc.
Please find the screenshot below,
I want the white arc in the above image to be transparent, so that I can see what is behind the view through arc.
It appears you want something like this:
To obtain that, I used almost identically your code, but I first filled the whole rect
with blue, and then I drew that the arc, using your code, but when we come to stroke the arc we stroke it with a blend mode of .clear
, thus erasing the area under the arc.
class MyView : UIView {
override init(frame:CGRect) {
super.init(frame:frame)
self.isOpaque = false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
// Drawing code
let arcHeight: CGFloat = 10
let arcColor = UIColor.blue
arcColor.setFill() // <--
let con = UIGraphicsGetCurrentContext() // <--
con?.fill(rect) // <--
let arcRect = CGRect(x: 0, y: rect.height - arcHeight, width: rect.width, height: arcHeight)
// ... same as your code ...
path.stroke(with: .clear, alpha: 1)
}
private func radians(_ degrees: CGFloat) -> CGFloat {
return degrees * CGFloat(M_PI) / 180
}
}