0

I'm trying to understand why i'm seeing only one of mine CGPathAddArc.

Code :

  var r: CGRect = self.myView.bounds
 var lay: CAShapeLayer = CAShapeLayer()
        var path: CGMutablePathRef = CGPathCreateMutable()
        CGPathAddArc(path, nil, 30, 30, 30, 0, (360 * CGFloat(M_PI))/180, true    )
        CGPathAddArc(path, nil, 70, 30, 30, 0, (360 * CGFloat(M_PI))/180, true    )

        CGPathAddRect(path, nil, r2)
 CGPathAddRect(path, nil, r)
        lay.path = path
        lay.fillRule = kCAFillRuleEvenOdd
        self.myView.layer.mask = lay

result :

enter image description here

Any suggestions? Thanks!

Community
  • 1
  • 1
Roi Mulia
  • 5,626
  • 11
  • 54
  • 105

2 Answers2

1

What you need to do is debug. How? Well, when in doubt, your first step should be to simplify. In this case, you should start by testing your code outside the context of a mask and a fill rule. When you do, you'll see that the arcs are in fact both present. I ran this reduced version of your code:

    let lay = CAShapeLayer()
    lay.frame = CGRectMake(20,20,400,400)
    let path = CGPathCreateMutable()
    CGPathAddArc(path, nil, 30, 30, 30, 0, 
        (360 * CGFloat(M_PI))/180, true)
    CGPathAddArc(path, nil, 70, 30, 30, 0, 
        (360 * CGFloat(M_PI))/180, true)
    lay.path = path
    self.view.layer.addSublayer(lay)

And this is what I got:

enter image description here

As you can see, both arcs are present. So your results must be due to some complication beyond the drawing of the arcs.

If we add the fill rule...

    lay.fillRule = kCAFillRuleEvenOdd

...we get this:

enter image description here

And if we introduce the mask element...

    // self.view.layer.addSublayer(lay)
    self.view.layer.mask = lay

...we get this:

enter image description here

Thus, using basic tests, you should be able to convince yourself of what this part of your code does. You can now introduce more and more of your actual code until you start getting undesirable results, and then you'll know what's causing the problem.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Awesome matt. Thank you so much! I'll check again whats wrong with my code than :) – Roi Mulia Mar 17 '16 at 08:44
  • Hey matt! I've understood why it didn't work + why i couldn't reproduce your code, It has to do with the angles, As you said - the code is fine, But if the angles aren't calculated properly, it's causes the path not be drawn. Check @gabbler answer :) Thank you! – Roi Mulia Mar 17 '16 at 08:55
1

If you push down the command key and click on CGPathAddArc function, you will see documentation.

/* Note that using values very near 2π can be problematic. For example,
   setting `startAngle' to 0, `endAngle' to 2π, and `clockwise' to true will
   draw nothing. (It's easy to see this by considering, instead of 0 and 2π,
   the values ε and 2π - ε, where ε is very small.) Due to round-off error,
   however, it's possible that passing the value `2 * M_PI' to approximate
   2π will numerically equal to 2π + δ, for some small δ; this will cause a
   full circle to be drawn.

   If you want a full circle to be drawn clockwise, you should set
   `startAngle' to 2π, `endAngle' to 0, and `clockwise' to true. This avoids
   the instability problems discussed above. */

Setting startAngle to 0, endAngle to 2π, and clockwise to true will draw nothing. If you want a full circle to be drawn clockwise, you should set startAngle to 2π, endAngle to 0, and clockwise to true. So that you can see all circles.

gabbler
  • 13,626
  • 4
  • 32
  • 44