8

I have these 2 functions bellow in my class which extends CAShapeLayer, but I can't get an arc with rounded end caps every time I draw the path. It looks always like this picture:

enter image description here

I already tried using kCALineCapRound with no success. Any ideas?

self.lineShape.lineCap = kCALineCapRound;

self.lineShape.lineJoin = kCALineJoinRound;

  private func mask() {
    let maskLayer = CAShapeLayer()
    maskLayer.bounds = self.bounds
    let ovalRect = self.hollowRect
    let path =  UIBezierPath(ovalInRect: ovalRect)
    path.appendPath(UIBezierPath(rect: maskLayer.bounds))
    maskLayer.path = path.CGPath
    maskLayer.lineShape.lineCap = kCALineCapRound;
    maskLayer.lineShape.lineJoin = kCALineJoinRound;
    maskLayer.position = self.currentCenter
    maskLayer.fillRule = kCAFillRuleEvenOdd
    self.mask = maskLayer
  }

  private func drawTrack(ctx: CGContext) {
    let adjustDegree = Math.adjustDegree(self.setting.startAngle, degree: self.degree)
    let centerX = self.currentCenter.x
    let centerY = self.currentCenter.y
    let radius = min(centerX, centerY)
    CGContextSetFillColorWithColor(ctx, self.setting.trackingColor.CGColor)
    CGContextSetLineCap(ctx, CGLineCap.Round)
    CGContextBeginPath(ctx)
    CGContextMoveToPoint(ctx, centerX, centerY)
    CGContextAddArc(ctx, centerX, centerY, radius,
      CGFloat(Math.degreesToRadians(self.setting.startAngle)),
      CGFloat(Math.degreesToRadians(adjustDegree)), 0)
    CGContextClosePath(ctx);
    CGContextFillPath(ctx);
  }
matt
  • 515,959
  • 87
  • 875
  • 1,141
Marco Nascimento
  • 832
  • 8
  • 15

2 Answers2

13

If this is a shape layer, you just say myShapeLayer.lineCap = "round". (I'm mystified by your mask and draw code, which has nothing to do with a shape layer, so I don't see how that's supposed to fit in.)

This is a shape layer with a circular path:

enter image description here

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 7
    Shouldn't you really use the defined constant (kCALineJoinRound, in this case) rather than the literal string "round"? – Duncan C Aug 01 '16 at 00:27
  • 1
    @DuncanC I did what the header told me to do. It worked. I stopped. – matt Aug 01 '16 at 00:32
  • Would you mind posting the code for that red circle here? – Marco Nascimento Aug 01 '16 at 13:15
  • @MarcoCoi Your question was "how to get the rounded cap on CAShapeLayer". I answered that. That is a shape layer, it draws an arc such you are drawing, it has rounded caps, and I told you the code for that. – matt Aug 01 '16 at 14:54
  • Alright, maybe thats something related to the mask. – Marco Nascimento Aug 01 '16 at 14:56
  • Maybe. As I said, I don't understand what the mask is doing. I don't understand what _any_ of your code is doing. I don't even see any shape layer in your code. And if there were a shape layer, I don't see why you'd need to mask it. I didn't mask my shape layer, but I easily achieved the shape you're looking for. If that's your real question, maybe that's what you should have asked. – matt Aug 01 '16 at 15:40
  • @matt , Thanks bro :), Any doc for style strings? – Rajamohan S Nov 02 '17 at 11:33
  • If you have multiple waypoints in your line segment(s) make sure you set cap style AND join style. `shapeLayer.lineJoin = kCALineJoinRound;` `shapeLayer.lineCap = kCALineCapRound;` – Albert Renshaw Jan 12 '20 at 06:00
5

Swift 4 version:

myShapeLayer.lineCap = .round

Documentation for line cap values can be found here

Vega
  • 27,856
  • 27
  • 95
  • 103
Tobbifee
  • 51
  • 2
  • 2