0

I want to create an inner shadow for an arc but I get half of a circle instead of the shadow (see image below).

My code is:

let rect = self.bounds
let segmentArcPath = UIBezierPath()
segmentArcPath.addArc(withCenter: rect.center,
                      radius: (rect.height - insetShadow) / 2,
                      startAngle: -.pi/2,
                      endAngle: value * 2 * .pi - .pi/2,
                      clockwise: true)

shadowPath = segmentArcPath.cgPath

The current result from the code above and the expected result

I have tried to add two paths (to not close the shadow), but without success:

let rect = self.bounds
let segmentArcPath = UIBezierPath()
segmentArcPath.addArc(withCenter: rect.center,
                      radius: (rect.height - insetShadow) / 2,
                      startAngle: internalStrokeStart,
                      endAngle: internalStrokeEnd,
                      clockwise: true)

let segmentArcPath2 = UIBezierPath()
segmentArcPath2.addArc(withCenter: rect.center,
                      radius: (rect.height - insetShadow) / 2 - 5,
                      startAngle: internalStrokeStart,
                      endAngle: internalStrokeEnd,
                      clockwise: false)

segmentArcPath.append(segmentArcPath2)
shadowPath = segmentArcPath.cgPath

How can I create a shadow as shown in the image above? Do you have any hints?

Hans Bondoka
  • 437
  • 1
  • 4
  • 14
  • 1
    Only create one `UIBezierPath`. After drawng the outer arc, draw a 5 unit line towards the center of the arc, then call `addArc` to add the inner arc to the same path. – vacawama Aug 24 '20 at 16:54

1 Answers1

0

As recommended by @vacawama:

Only create one UIBezierPath. After drawng the outer arc, draw a 5 unit line towards the center of the arc, then call addArc to add the inner arc to the same path

let rect = self.bounds
let outerRadius = (rect.height - insetShadow) / 2
let segmentArcPath = UIBezierPath()
segmentArcPath.addArc(withCenter: rect.center,
                      radius: outerRadius,
                      startAngle: internalStrokeStart,
                      endAngle: internalStrokeEnd,
                      clockwise: true)
let innerCircleRadius = outerRadius - 2
let startPointXInnerCircle = cos(internalStrokeEnd) * innerCircleRadius + rect.center.x
let startPointYInnerCircle = sin(internalStrokeEnd) * innerCircleRadius + rect.center.y

segmentArcPath.addLine(to: CGPoint(x: startPointXInnerCircle, y: startPointYInnerCircle))

segmentArcPath.addArc(withCenter: rect.center,
                      radius: innerCircleRadius,
                      startAngle: internalStrokeEnd,
                      endAngle: internalStrokeStart,
                      clockwise: false)

shadowPath = segmentArcPath.cgPath
Hans Bondoka
  • 437
  • 1
  • 4
  • 14
  • Why add a line rather with `addLine(to:)` rather than `move(to:)`? Wouldn't that add an artifact in the drawing? – Duncan C Aug 24 '20 at 19:24
  • @DuncanC: For the shadow you need a closed path. When the path is not closed (e.g. via move) it will automatically be closed with the shortest possible path and in a consequence leads to artifacts. – Hans Bondoka Aug 25 '20 at 06:43