I'm trying to achieve this design in iOS UIKit:
Using bezier path I have completed it but I am unable to achieve the inverted curve from the left side.
I'm attaching the code snippet that I use:
class ArcView : UIView {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func setupViewWith(textToDisplay:String,imageNamed:String,backgroundColor:UIColor){
setupView(backgroundColor: backgroundColor)
}
func setupView(backgroundColor:UIColor){
let criclepath : UIBezierPath = getCirclePath()
let shapeLayer = CAShapeLayer()
shapeLayer.position = CGPoint(x: 0, y: 0)
shapeLayer.path = criclepath.cgPath
shapeLayer.lineWidth = 1.5
shapeLayer.strokeColor = UIColor.white.cgColor
shapeLayer.fillColor = backgroundColor.cgColor
self.layer.addSublayer(shapeLayer)
let supportpath : UIBezierPath = getPath()
let supportLayer = CAShapeLayer()
supportLayer.path = supportpath.cgPath
supportLayer.lineWidth = 1.5
supportLayer.strokeColor = UIColor.white.cgColor
supportLayer.fillColor = backgroundColor.cgColor
self.layer.addSublayer(supportLayer)
}
func getPath()->UIBezierPath{
let height = self.frame.size.height
let width = self.frame.size.width
let halfHeight = height/2.0
let xPosition = 40.0
let path = UIBezierPath()
path.move(to: CGPoint(x: xPosition, y: 0))
path.addLine(to: CGPoint(x: width-halfHeight, y: 0))
path.addArc(withCenter: CGPoint(x: width-halfHeight, y: halfHeight),
radius: halfHeight,
startAngle: CGFloat(270).toRadians(),
endAngle: CGFloat(90).toRadians(),
clockwise: true)
path.addLine(to: CGPoint(x: xPosition, y: height))
path.addCurve(to: CGPoint(x: xPosition, y: 0),
controlPoint1: CGPoint(x: xPosition+25 , y: 30),
controlPoint2: CGPoint(x: xPosition+10, y: 5))
path.close()
return path
}
func getCirclePath()->UIBezierPath{
let path = UIBezierPath(ovalIn: CGRect(x: 0,
y: 0,
width: self.frame.size.height,
height: self.frame.size.height))
path.close()
return path
}
}
extension CGFloat {
func toRadians() -> CGFloat {
return self * CGFloat(Double.pi) / 180.0
}
}
I'm using two shape layers, one for the circle in the left side and one for the arcShape in the right side.
My result using the above snippet:


Using some trigonometry you can get the exact result you need no matter what size the view's frame is. The following code is based on your original code with some changed calculations. It also allows for a user define line width and adjust itself so the stroked line is all within the confines of the view.
Here's some example code. The above and the following can all be copied into a playground to test the results.
Here's the output: