Search code examples
iosobjective-cswiftuibezierpath

Create a point inside a UIBezierPath


enter image description here

I need to make the path as in the image. I have figured out the circle part but stuck on how to place the point inside the circular part.


Solution

  • Create a brand new UIView. In my example, I've named mine ProdView. Copy the following code:

        import UIKit
    
        @IBDesignable
        class ProdView: UIView {
            override func draw(_ rect: CGRect) {
            // Drawing code
    
            let lineWidth: CGFloat = 2.0
    
            let canvas = CGRect(x: rect.origin.x + 1, y: rect.origin.y + 1, width: rect.width - 2, height: rect.height - 2)
    
            let circlePath = UIBezierPath(ovalIn: canvas)
    
            UIColor.black.setStroke()
    
            UIColor.black.setFill()
    
            circlePath.lineWidth = lineWidth
    
            circlePath.stroke()
    
            let circleDotWidth: CGFloat = 10
    
            let circleDot = UIBezierPath(ovalIn: CGRect(x: -circleDotWidth / 2,
                                                    y: -circleDotWidth / 2,
                                                    width: circleDotWidth,
                                                    height: circleDotWidth))
    
            let context = UIGraphicsGetCurrentContext()!
    
            context.translateBy(x: rect.width / 2, y: rect.height / 2)
    
            context.saveGState()
    
            let angle: CGFloat = (5 * CGFloat(Double.pi) / 3) - (CGFloat(Double.pi) / 2)
    
            context.rotate(by: angle)
    
            context.translateBy(x: 0, y: rect.height / 2 - (circleDotWidth / 2) + 4)
    
            circleDot.fill()
    
            context.restoreGState()
    
          }
    
    
        }
    

    In the example above, I created the circle and gave it a stroke. I then created the circle dot taking into account it's width for its x and y CGRect values. I then get the current context and translate it to the centre of the view's rect. I then save the current context and rotate the context to 5pi/3 radians which I think is fairly close to where you want the dot. I subtract pi/2 because by default the context is skewed pi/2 radians from the start angle (or 0). I then translate the context to right where I want to fill the dot taking into account the circle dot's width and the line width of the circle and fill it to make it visible.

    When I take out a UIView onto ViewController, setup the constraints and change it's class to ProdView and I get the following results (remember ProdView is IBDesignable so we can see the results in Storyboard):

    Circle Dot