Swift/UIView Draw something like tachometer - swift

I think I am having kind of a blackout but I am not able to simply work with BezierPaths within Swift. Want I want to do is something like on the screenshot:
So it's just something like a tachometer with three colours:
What I do have is the following:
diagram.layer.borderWidth = 4.0
diagram.layer.borderColor = UIColor.black.cgColor
let pi = CGFloat(Float.pi)
let start:CGFloat = 0.0
let end :CGFloat = pi
let radius : CGFloat = diagram.frame.width/3
let middle = CGPoint(x: diagram.frame.size.width/2, y:diagram.frame.size.height/2)
let path: UIBezierPath = UIBezierPath();
path.addArc(
withCenter: CGPoint(x: middle.x, y: middle.y),
radius: radius,
startAngle: start,
endAngle: end,
clockwise: false
)
let layer = CAShapeLayer()
layer.fillColor = UIColor.clear.cgColor
layer.strokeColor = UIColor.red.cgColor
layer.path = path.cgPath
diagram.layer.addSublayer(layer)
That is just the first arc, but it makes me crazy. It is not centred, which is odd because I am using the size of my Uiview for it. My UIView is obviously called "diagram".
Does anyone have a great example with Swift how to do something like on the screenshot?
Thanks for reading!
=======
This is just code relating to the answer of andykkt
func drawCompareGauge(frame: CGRect = CGRect(x: 0, y: 0, width: 180, height: 92), leftPercentage: CGFloat = 0.5) {
//// General Declarations
let context = UIGraphicsGetCurrentContext()
//// Color Declarations
let leftColor = UIColor(red: 0.278, green: 0.757, blue: 0.749, alpha: 1.000)
let rightColor = UIColor(red: 0.557, green: 0.400, blue: 0.867, alpha: 1.000)
//// Variable Declarations
let leftDashed: CGFloat = 247 * leftPercentage
//// rightRing Drawing
let rightRingPath = UIBezierPath()
rightRingPath.move(to: CGPoint(x: frame.minX + 11.5, y: frame.minY + 91.5))
rightRingPath.addCurve(to: CGPoint(x: frame.minX + 42.73, y: frame.minY + 28.82), controlPoint1: CGPoint(x: frame.minX + 11.5, y: frame.minY + 65.89), controlPoint2: CGPoint(x: frame.minX + 23.76, y: frame.minY + 43.15))
rightRingPath.addCurve(to: CGPoint(x: frame.minX + 90, y: frame.minY + 13), controlPoint1: CGPoint(x: frame.minX + 55.88, y: frame.minY + 18.89), controlPoint2: CGPoint(x: frame.minX + 72.25, y: frame.minY + 13))
rightRingPath.addCurve(to: CGPoint(x: frame.minX + 168.5, y: frame.minY + 91.5), controlPoint1: CGPoint(x: frame.minX + 133.35, y: frame.minY + 13), controlPoint2: CGPoint(x: frame.minX + 168.5, y: frame.minY + 48.15))
rightColor.setStroke()
rightRingPath.lineWidth = 23
context?.saveGState()
//CGContextSetLineDash(context, 0, [247, 247], 2)
//context!.setLineDash(phase: <#T##CGFloat#>, lengths: <#T##[CGFloat]#>)
context?.setLineDash(phase: 0, lengths: [247,247])
//problem
rightRingPath.stroke()
context?.restoreGState()
//// leftRing Drawing
let leftRingPath = UIBezierPath()
leftRingPath.move(to: CGPoint(x: frame.minX + 11.5, y: frame.minY + 91.5))
leftRingPath.addCurve(to: CGPoint(x: frame.minX + 42.73, y: frame.minY + 28.82), controlPoint1: CGPoint(x: frame.minX + 11.5, y: frame.minY + 65.89), controlPoint2: CGPoint(x: frame.minX + 23.76, y: frame.minY + 43.15))
leftRingPath.addCurve(to: CGPoint(x: frame.minX + 90, y: frame.minY + 13), controlPoint1: CGPoint(x: frame.minX + 55.88, y: frame.minY + 18.89), controlPoint2: CGPoint(x: frame.minX + 72.25, y: frame.minY + 13))
leftRingPath.addCurve(to: CGPoint(x: frame.minX + 168.5, y: frame.minY + 91.5), controlPoint1: CGPoint(x: frame.minX + 133.35, y: frame.minY + 13), controlPoint2: CGPoint(x: frame.minX + 168.5, y: frame.minY + 48.15))
leftColor.setStroke()
leftRingPath.lineWidth = 23
context?.saveGState()
//context!.setLineDash(context, 0, [leftDashed, 247], 2)
//Problem
context?.setLineDash(phase: 0, lengths: [leftDashed,247])
leftRingPath.stroke()
context?.restoreGState()
//// Text Drawing
let textRect = CGRect(x: frame.minX + 7, y: frame.minY + 74, width: 11, height: 21)
let textTextContent = NSString(string: "L")
let textStyle = NSMutableParagraphStyle()
textStyle.alignment = .left
let textFontAttributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: UIFont.systemFontSize), NSAttributedStringKey.foregroundColor: UIColor.white, NSAttributedStringKey.paragraphStyle: textStyle]
let textTextHeight: CGFloat = textTextContent.boundingRect(with: CGSize(width: textRect.width, height: CGFloat.infinity), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: textFontAttributes, context: nil).size.height
context?.saveGState()
context?.clip(to: textRect)
textTextContent.draw(in: CGRect(x: textRect.minX, y: textRect.minY + (textRect.height - textTextHeight) / 2, width: textRect.width, height: textTextHeight), withAttributes: textFontAttributes)
context?.restoreGState()
//// Text 2 Drawing
let text2Rect = CGRect(x: frame.minX + 164, y: frame.minY + 76, width: 11, height: 17)
let text2TextContent = NSString(string: "R")
let text2Style = NSMutableParagraphStyle()
text2Style.alignment = .left
let text2FontAttributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: UIFont.systemFontSize), NSAttributedStringKey.foregroundColor: UIColor.white, NSAttributedStringKey.paragraphStyle: text2Style]
let text2TextHeight: CGFloat = text2TextContent.boundingRect(with: CGSize(width: text2Rect.width, height: CGFloat.infinity), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: text2FontAttributes, context: nil).size.height
context?.saveGState()
context?.clip(to: text2Rect)
//CGContextClipToRect(context!, text2Rect)
text2TextContent.draw(in: CGRect(x: text2Rect.minX, y: text2Rect.minY + (text2Rect.height - text2TextHeight) / 2, width: text2Rect.width, height: text2TextHeight), withAttributes: text2FontAttributes)
context?.restoreGState()
}

I draw it from "PaintCode" as an example, you can use paintcode to draw how you want it to be.
#IBDesignable class GaugeView: UIView {
#IBInspectable var leftPercentage: CGFloat = 0.708 {
didSet {
setNeedsDisplay()
}
}
#IBInspectable var otherPercentage: CGFloat = 0.206 {
didSet {
setNeedsDisplay()
}
}
override func draw(_ rect: CGRect) {
// Drawing code
drawCompareGauge(frame: bounds, leftPercentage: leftPercentage, otherPercentage: otherPercentage)
}
func drawCompareGauge(frame: CGRect = CGRect(x: 0, y: 0, width: 180, height: 92), leftPercentage: CGFloat = 0.708, otherPercentage: CGFloat = 0.206) {
//// General Declarations
guard let context = UIGraphicsGetCurrentContext() else { return }
//// Color Declarations
let leftColor = UIColor(red: 0.278, green: 0.757, blue: 0.749, alpha: 1.000)
let rightColor = UIColor(red: 0.557, green: 0.400, blue: 0.867, alpha: 1.000)
let otherColor = UIColor(red: 0.800, green: 0.320, blue: 0.320, alpha: 1.000)
//// Variable Declarations
let leftDashed: CGFloat = 247 * leftPercentage
let otherDashed: CGFloat = 247 * otherPercentage
//// rightRing Drawing
let rightRingPath = UIBezierPath()
rightRingPath.move(to: CGPoint(x: frame.minX + 11.5, y: frame.minY + 91.5))
rightRingPath.addCurve(to: CGPoint(x: frame.minX + 42.73, y: frame.minY + 28.82), controlPoint1: CGPoint(x: frame.minX + 11.5, y: frame.minY + 65.89), controlPoint2: CGPoint(x: frame.minX + 23.76, y: frame.minY + 43.15))
rightRingPath.addCurve(to: CGPoint(x: frame.minX + 90, y: frame.minY + 13), controlPoint1: CGPoint(x: frame.minX + 55.88, y: frame.minY + 18.89), controlPoint2: CGPoint(x: frame.minX + 72.25, y: frame.minY + 13))
rightRingPath.addCurve(to: CGPoint(x: frame.minX + 168.5, y: frame.minY + 91.5), controlPoint1: CGPoint(x: frame.minX + 133.35, y: frame.minY + 13), controlPoint2: CGPoint(x: frame.minX + 168.5, y: frame.minY + 48.15))
rightColor.setStroke()
rightRingPath.lineWidth = 23
context.saveGState()
context.setLineDash(phase: 0, lengths: [247, 247])
rightRingPath.stroke()
context.restoreGState()
//// leftRing Drawing
let leftRingPath = UIBezierPath()
leftRingPath.move(to: CGPoint(x: frame.minX + 11.5, y: frame.minY + 91.5))
leftRingPath.addCurve(to: CGPoint(x: frame.minX + 42.73, y: frame.minY + 28.82), controlPoint1: CGPoint(x: frame.minX + 11.5, y: frame.minY + 65.89), controlPoint2: CGPoint(x: frame.minX + 23.76, y: frame.minY + 43.15))
leftRingPath.addCurve(to: CGPoint(x: frame.minX + 90, y: frame.minY + 13), controlPoint1: CGPoint(x: frame.minX + 55.88, y: frame.minY + 18.89), controlPoint2: CGPoint(x: frame.minX + 72.25, y: frame.minY + 13))
leftRingPath.addCurve(to: CGPoint(x: frame.minX + 168.5, y: frame.minY + 91.5), controlPoint1: CGPoint(x: frame.minX + 133.35, y: frame.minY + 13), controlPoint2: CGPoint(x: frame.minX + 168.5, y: frame.minY + 48.15))
leftColor.setStroke()
leftRingPath.lineWidth = 23
context.saveGState()
context.setLineDash(phase: 0, lengths: [leftDashed, 247])
leftRingPath.stroke()
context.restoreGState()
//// leftRing 2 Drawing
let leftRing2Path = UIBezierPath()
leftRing2Path.move(to: CGPoint(x: frame.minX + 11.5, y: frame.minY + 91.5))
leftRing2Path.addCurve(to: CGPoint(x: frame.minX + 42.73, y: frame.minY + 28.82), controlPoint1: CGPoint(x: frame.minX + 11.5, y: frame.minY + 65.89), controlPoint2: CGPoint(x: frame.minX + 23.76, y: frame.minY + 43.15))
leftRing2Path.addCurve(to: CGPoint(x: frame.minX + 90, y: frame.minY + 13), controlPoint1: CGPoint(x: frame.minX + 55.88, y: frame.minY + 18.89), controlPoint2: CGPoint(x: frame.minX + 72.25, y: frame.minY + 13))
leftRing2Path.addCurve(to: CGPoint(x: frame.minX + 168.5, y: frame.minY + 91.5), controlPoint1: CGPoint(x: frame.minX + 133.35, y: frame.minY + 13), controlPoint2: CGPoint(x: frame.minX + 168.5, y: frame.minY + 48.15))
otherColor.setStroke()
leftRing2Path.lineWidth = 23
context.saveGState()
context.setLineDash(phase: 0, lengths: [otherDashed, 247])
leftRing2Path.stroke()
context.restoreGState()
}
I have changed the code to class and support latest xcode & swift. You can just place a this view on view controller to see the result and change leftPercentage animate gauge.
==============================
I have updated the code to display 3 different value as gauge, I hope this help you to figure it out. Please see below gif for this control in action.

Related

iOS: Chat bubble change position of tail

I'm trying to achive this layout
[LAYOUT TO ACHIEVE]
and right now I have gradient part done, blur part done, and also bezier path mostly done. My question is that I can't replace TAIL from bottom right part to top left part (to be similar like in the picture).
[LAYOUT ACHIEVED]
My Code I wrote for acheiving:
public final class BubbleView: UIView {
public var configuration: Configuration = Configuration.defaultConfiguration {
didSet {
setNeedsLayout()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
super.backgroundColor = .clear
}
public override func draw(_ rect: CGRect) {
let hasBlurSubview = subviews.compactMap({$0}).contains(where: {$0 is UIVisualEffectView })
guard !hasBlurSubview else {
return
}
let lineWidth = configuration.lineWidth
let bezierPath = UIBezierPath()
bezierPath.lineWidth = lineWidth
let bottom = rect.height - lineWidth
let right = rect.width - lineWidth
let top = 0.0
let left = 0.0
bezierPath.move(to: CGPoint(x: right - 22, y: bottom))
bezierPath.addLine(to: CGPoint(x: 17 + lineWidth, y: bottom))
bezierPath.addCurve(to: CGPoint(x: left, y: bottom - 18), controlPoint1: CGPoint(x: 7.61 + lineWidth, y: bottom), controlPoint2: CGPoint(x: left, y: bottom - 7.61))
bezierPath.addLine(to: CGPoint(x: left, y: 17 + lineWidth))
bezierPath.addCurve(to: CGPoint(x: 17 + borderWidth, y: top), controlPoint1: CGPoint(x: left, y: 7.61 + lineWidth), controlPoint2: CGPoint(x: 7.61 + lineWidth, y: top))
bezierPath.addLine(to: CGPoint(x: right - 21, y: top))
bezierPath.addCurve(to: CGPoint(x: right - 4, y: 17 + lineWidth), controlPoint1: CGPoint(x: right - 11.61, y: top), controlPoint2: CGPoint(x: right - 4, y: 7.61 + lineWidth))
bezierPath.addLine(to: CGPoint(x: right - 4, y: bottom - 11))
bezierPath.addCurve(to: CGPoint(x: right, y: bottom), controlPoint1: CGPoint(x: right - 4, y: bottom - 1), controlPoint2: CGPoint(x: right, y: bottom))
bezierPath.addLine(to: CGPoint(x: right + 0.05, y: bottom - 0.01))
bezierPath.addCurve(to: CGPoint(x: right - 11.04, y: bottom - 4.04), controlPoint1: CGPoint(x: right - 4.07, y: bottom + 0.43), controlPoint2: CGPoint(x: right - 8.16, y: bottom - 1.06))
bezierPath.addCurve(to: CGPoint(x: right - 22, y: bottom), controlPoint1: CGPoint(x: right - 16, y: bottom), controlPoint2: CGPoint(x: right - 19, y: bottom))
bezierPath.close()
let blurEffect = UIVisualEffectView(effect: UIBlurEffect(style: .light))
blurEffect.alpha = configuration.blurAlpha
blurEffect.frame = bezierPath.bounds
let mask = CAShapeLayer()
mask.path = bezierPath.cgPath
blurEffect.layer.mask = mask
insertSubview(blurEffect, at: 0)
let gradient = CAGradientLayer()
gradient.frame = CGRect(origin: CGPoint.zero, size: size)
gradient.colors = configuration.borderGradientColors.map({$0.cgColor})
gradient.startPoint = configuration.borderGradientStartPoint
gradient.endPoint = configuration.borderGradientEndPoint
let shape = CAShapeLayer()
shape.lineWidth = lineWidth
shape.path = bezierPath.cgPath
shape.strokeColor = UIColor.black.cgColor
shape.fillColor = UIColor.clear.cgColor
gradient.mask = shape
blurEffect.layer.addSublayer(gradient)
}
}
public class Configuration {
static var defaultConfiguration: Configuration {
return .init(
lineWidth: 2.0,
blurAlpha: 0.95,
borderGradientColors: [Assets.Colors.white05.color, Assets.Colors.white01.color],
borderGradientStartPoint: CGPoint(x: 0.0, y: 0.5),
borderGradientEndPoint: CGPoint(x: 1.0, y: 0.5)
)
}
var lineWidth: CGFloat
var blurAlpha: CGFloat
var borderGradientColors: [UIColor]
var borderGradientStartPoint: CGPoint
var borderGradientEndPoint: CGPoint
init(
lineWidth: CGFloat,
blurAlpha: CGFloat,
borderGradientColors: [UIColor],
borderGradientStartPoint: CGPoint,
borderGradientEndPoint: CGPoint
) {
self.lineWidth = lineWidth
self.blurAlpha = blurAlpha
self.borderGradientColors = borderGradientColors
self.borderGradientStartPoint = borderGradientStartPoint
self.borderGradientEndPoint = borderGradientEndPoint
}
}

Need to create custom shape for UIView Swift

I need to create this custom UIView for my project.I need to achieve this
I was doing trial and error by creating, My own custom UIView and then drawing on it.
I'm working on this
My Question is, if I'm able to draw my custom shape, How will I clip-off the remaining white space of the UIView
func drawCustomShape() {
let viewSize = self.frame.size
let buttonSlotRadius = CGFloat(30)
let effectiveViewHeight = viewSize.height - buttonSlotRadius
let path = UIBezierPath()
path.move(to: CGPoint(x: 30, y: 0))
path.addLine(to: CGPoint(x: viewSize.width - 30, y: 0))
path.addArc(withCenter: CGPoint(x: viewSize.width - 30,
y: 30),
radius: 30,
startAngle: .pi * 3 / 2,
endAngle: 0,
clockwise: true)
path.addLine(to: CGPoint(x: viewSize.width, y: effectiveViewHeight))
path.addArc(withCenter: CGPoint(x: viewSize.width - 30,
y: effectiveViewHeight - 30),
radius: 30,
startAngle: 0,
endAngle: .pi / 2,
clockwise: true)
path.addLine(to: CGPoint(x: viewSize.width / 4, y: effectiveViewHeight))
// close path join to origin
path.close()
UIColor.secondarySystemFill.setFill()
path.fill()
path.lineWidth = 6.0
path.stroke()
}
You can use UIView with clear background color, and use CAShapeLayer with desired path like this:
extension UIView {
func drawCustomShape() {
let cornerRadius: CGFloat = 18.0
let shapeOffset = self.frame.size.height * 0.2
//create shape layer
let shapeLayer = CAShapeLayer()
shapeLayer.frame = self.bounds
shapeLayer.lineWidth = 1.0
shapeLayer.fillColor = UIColor.white.cgColor
self.layer.addSublayer(shapeLayer)
//create path
let path = UIBezierPath()
//top left point
path.move(to: CGPoint(x: 0, y: cornerRadius))
//top left corner
path.addQuadCurve(to: CGPoint(x: cornerRadius, y: 0),
controlPoint: CGPoint(x: 0, y: 0))
//top right point
path.addLine(to: CGPoint(x: self.frame.size.width - cornerRadius, y: 0))
//top right corner
path.addQuadCurve(to: CGPoint(x: self.frame.size.width, y: cornerRadius),
controlPoint: CGPoint(x: self.frame.size.width, y: 0))
//bottom right point
path.addLine(to: CGPoint(x: self.frame.size.width, y: self.frame.size.height - shapeOffset - cornerRadius))
//bottom right corner
path.addQuadCurve(to: CGPoint(x: self.frame.size.width - cornerRadius, y: self.frame.size.height - shapeOffset),
controlPoint: CGPoint(x: self.frame.size.width, y: self.frame.size.height - shapeOffset))
//bottom left
path.addLine(to: CGPoint(x: cornerRadius, y: self.frame.size.height))
//bottom left corner
path.addQuadCurve(to: CGPoint(x: 0, y: self.frame.size.height - cornerRadius),
controlPoint: CGPoint(x: 0, y: self.frame.size.height))
path.close()
shapeLayer.path = path.cgPath
}
Usage:
myView.drawCustomShape()
Result:

Xcode Swift, Keyframe animation has unwanted delay between animations loops on a bezier curve

Im attempting to animate a UIView along an oval using a bezier curve. The code works except that there is a delay between each loop of the animation. I'm at a loss as to what is causing this.
let myView = UIView()
myView.backgroundColor = UIColor.blue
myView.frame = CGRect(x: 0, y:0, width: 30, height: 30)
let path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 200, height: 200))
let animation = CAKeyframeAnimation(keyPath: "position")
animation.path = path.cgPath
animation.repeatCount = 1000
animation.duration = 1
myView.layer.add(animation, forKey: "animate along path")
Found a solution. The pause between animation loops only takes place when making a path with the UIBezierPath(ovalIn:) constructor. There's no delay when manually making your own path. So I made my own oval.
Replaced this
let path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 200, height: 200))
with this
let rect = CGRect(x: 0, y: 0, width: 200, height: 200)
let path = UIBezierPath()
path.move(to: CGPoint(x: rect.maxX, y: rect.midY))
path.addQuadCurve(to: CGPoint(x: rect.midX, y: rect.maxY), controlPoint: CGPoint(x: rect.maxX, y: rect.maxY))
path.addQuadCurve(to: CGPoint(x: rect.minX, y: rect.midY), controlPoint: CGPoint(x: rect.minX, y: rect.maxY))
path.addQuadCurve(to: CGPoint(x: rect.midX, y: rect.minY), controlPoint: CGPoint(x: rect.minX, y: rect.minY))
path.addQuadCurve(to: CGPoint(x: rect.maxX, y: rect.midY), controlPoint: CGPoint(x: rect.maxX, y: rect.minY))

How To make Label like below image in swift

I have working on chatting app and i have try to make label like bellow image but i can't done anyone can help me.
In Xcode go to your assets, select your bubble image and click on show slicing.
Slicing enable your image to stretch with the given slices without deforming.
It is complicated to draw this form using CoreGraphics. I have achieved this result which is not perfect.You can use this code in "drawRect" method, and after you have to draw (or to override the layout) the text.
func drawCanvas1(frame: CGRect = CGRect(x: 0, y: 0, width: 120, height: 100)) {
//// General Declarations
// This non-generic function dramatically improves compilation times of complex expressions.
func fastFloor(_ x: CGFloat) -> CGFloat { return floor(x) }
//// Rectangle Drawing
let rectanglePath = UIBezierPath(roundedRect: CGRect(x: frame.minX + fastFloor(frame.width * 0.25000 + 0.5), y: frame.minY + fastFloor(frame.height * 0.00000 + 0.5), width: fastFloor(frame.width * 1.00000 + 0.5) - fastFloor(frame.width * 0.25000 + 0.5), height: fastFloor(frame.height * 1.00000 + 0.5) - fastFloor(frame.height * 0.00000 + 0.5)), cornerRadius: 10)
UIColor.gray.setFill()
rectanglePath.fill()
//// Bezier 3 Drawing
let bezier3Path = UIBezierPath()
bezier3Path.move(to: CGPoint(x: frame.minX + 0.5, y: frame.minY + 85.5))
bezier3Path.addCurve(to: CGPoint(x: frame.minX + 30.5, y: frame.minY + 64.5), controlPoint1: CGPoint(x: frame.minX + 0.5, y: frame.minY + 85.5), controlPoint2: CGPoint(x: frame.minX + 30.5, y: frame.minY + 85.5))
bezier3Path.addCurve(to: CGPoint(x: frame.minX + 43.5, y: frame.minY + 99.5), controlPoint1: CGPoint(x: frame.minX + 30.5, y: frame.minY + 43.5), controlPoint2: CGPoint(x: frame.minX + 43.5, y: frame.minY + 99.5))
bezier3Path.move(to: CGPoint(x: frame.minX + 0.59, y: frame.minY + 85.5))
bezier3Path.addCurve(to: CGPoint(x: frame.minX + 43.5, y: frame.minY + 99.5), controlPoint1: CGPoint(x: frame.minX - 0.43, y: frame.minY + 86.43), controlPoint2: CGPoint(x: frame.minX + 6.72, y: frame.minY + 99.5))
UIColor.gray.setFill()
bezier3Path.fill()
UIColor.gray.setStroke()
bezier3Path.lineWidth = 1
bezier3Path.lineCapStyle = .round
bezier3Path.lineJoinStyle = .round
bezier3Path.stroke()
}
I recommend you to create an image in Illustrator or some other program with this form and to use it as background.

unable to create exact path

I want to create image view like this.
With Bezier path, the code i tried is
let path = UIBezierPath()
path.move(to: CGPoint(x: myImage.frame.size.width - 10 , y: myImage.frame.size.height))
path.addLine(to: CGPoint(x: myImage.frame.size.width - 20 , y: 20))
path.addLine(to: CGPoint(x: myImage.frame.size.width, y: 20))
path.addArc(withCenter: CGPoint(x: myImage.frame.size.width/2, y: myImage.frame.size.height/2), radius: myImage.frame.size.width/2, startAngle:-CGFloat(M_PI_2), endAngle: CGFloat(M_PI_2), clockwise: false)
//
path.move(to: CGPoint(x: myImage.frame.size.width/2, y: myImage.frame.size.height))
path.close()
UIColor.red.setFill()
path.stroke()
path.reversing()
code
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 153.5, y: 137.5))
bezierPath.addCurve(to: CGPoint(x: 63.5, y: 196.5), controlPoint1: CGPoint(x: 130.5, y: 137.5), controlPoint2: CGPoint(x: 63.5, y: 120.37))
bezierPath.addCurve(to: CGPoint(x: 63.5, y: 310.5), controlPoint1: CGPoint(x: 63.5, y: 260.99), controlPoint2: CGPoint(x: 63.5, y: 218.5))
bezierPath.addCurve(to: CGPoint(x: 88.5, y: 352.5), controlPoint1: CGPoint(x: 63.5, y: 333.5), controlPoint2: CGPoint(x: 73.5, y: 347.5))
bezierPath.addCurve(to: CGPoint(x: 218.5, y: 360.5), controlPoint1: CGPoint(x: 137.23, y: 368.74), controlPoint2: CGPoint(x: 218.5, y: 360.5))
bezierPath.addCurve(to: CGPoint(x: 240.5, y: 309.5), controlPoint1: CGPoint(x: 218.5, y: 360.5), controlPoint2: CGPoint(x: 240.5, y: 337))
bezierPath.addCurve(to: CGPoint(x: 222.5, y: 249.5), controlPoint1: CGPoint(x: 240.5, y: 282), controlPoint2: CGPoint(x: 222.5, y: 249.5))
bezierPath.addCurve(to: CGPoint(x: 240.5, y: 196.5), controlPoint1: CGPoint(x: 222.5, y: 249.5), controlPoint2: CGPoint(x: 240.5, y: 224.5))
bezierPath.addCurve(to: CGPoint(x: 218.5, y: 137.5), controlPoint1: CGPoint(x: 240.5, y: 168.5), controlPoint2: CGPoint(x: 218.5, y: 137.5))
bezierPath.addCurve(to: CGPoint(x: 153.5, y: 137.5), controlPoint1: CGPoint(x: 218.5, y: 137.5), controlPoint2: CGPoint(x: 201.5, y: 137.5))
bezierPath.close()
UIColor.gray.setFill()
bezierPath.fill()
UIColor.black.setStroke()
bezierPath.lineWidth = 1
bezierPath.stroke()
output