Common outline for two shapes drawn in drawRect: ObjectiveC - ios

I have two shapes in a UIView - one, an ellipse and two, a triangle drawn using UIBezierPath. I need to draw the outline of these two shapes combined. How can I do it?

You can do an "outside" stroke (like stroke->outside in photoshop/pixelmator) by calling stroke to draw the outline and setting the inverse of your shapes as the clipping path first. To do the inverse of the clipping path see this answer: https://stackoverflow.com/a/10639523/461492 (read comments too).
So here are the steps:
Set the full area as the clipping path.
Call CGContextEOClip() for each of your shapes as described in the comments to the answer linked above.
Stroke your shapes.
This might not be exactly what you want - it will draw the stroke as normal but the whole interior (the fill area) of your shapes will not be drawn. So whereas the thickness of the stroke would normally extend within the interior of your shapes, and the internal angles of your stroke would normally have the correct corners (rounded/mitered) - in this case it would be more like you stroked the shapes then deleted the fill-area, or did an "outside" stroke in an image editing program.

Related

Swift 3, draw circle with special lineCap

Currently I'm using CAShapeLayer and UIBezierPath to draw a line for avatar. It's Ok for the normal one with lineCap = kCALineCapRound. BUT I've been STRUGGLING to draw line with START and END lineCap like image below:
You can't draw this circle with a shape layer, because a shape layer supports only one single stroke color. You should write your own layer class where you should draw three separate circle segments with kCALineCapRound:
A full yellow circle.
Draw the blue segment over the yellow circle. It is visible and you can see the rounded ends.
Draw a segment of the yellow circle, say 5 degrees of the top. Then you can also see the rounded end of the yellow line.
You should use CGPath and CGContext instead of UIBezierPath.

How can I visually display points in a UIBezierPath?

I'm trying to change the shape of a CAShapeLayer from a circle to a different shape. Looking at this question:
Smooth shape shift animation
I found the solution but my question is how can I visually see how many points a UIBezierPath has. Is there a way to color a point different than the line it produces?
For example,it's simple with a line to understand that there are two point, but if we make a circle with bezierPathWithRoundedRect, does that count as one point or are there more?
You would need to add the circle yourself to visually see the dots. Just keep track of the CGPoints you give to the path and draw a circle around each one.
Btw.. if you use PaintCode, you can edit the bezier path and see the point -- it's very useful.

Masking CALayer with Lines

I'm trying to find an efficient way to perform the following clipping operation on a CAShapeLayer that I have.
What I'm Trying to Do
I have a CAShapeLayer whose circular path consists of a UIBezierPath that has been constructed using the method [UIBezierPath bezierPathWithArcCenter:] (this is a full circle from 0 to 2PI radians), and inside of that circle, I want to cut out multiple lines that are drawn at different angles, making the area below the cut out lines transparent on the circle. I want these lines to begin and end at points on the outside of the circle aka the edges of the CAShapeLayer's path.
I'm wondering whether there is a way to use the mask property on the CAShapeLayer to accomplish this, or whether I should abandon the idea of cutting out from the full circle and just draw each arced triangle separately as different CAShapeLayers.
Thank you for your any help!
I ended up solving this by forgetting about using masks. Instead, I just constructed a UIBezierPath using the moveToPoint: and addLineToPoint: methods in order to draw the desired portions of the circle.

Cocoa CoreGraphics: How to fill multiple shapes with a gradient

I have logo text drawn as shapes (closed CGBezierPaths) that I want to fill with a gradient.(Light at the top, moving to dark at the bottom) How can I fill each shape with gradient such that the gradient is the same color for each shape.
The problem is drawing the gradient for each shape, if the letters are different height then the gradient has a different ramp since the distance is smaller. Hope that makes sense.
So basically I want draw a single gradient down the rect and use all the shapes as a clipping mask. Is this possible?
For gradient drawing - take a look at this project:
https://github.com/wczekalski/CDPieMenu
It creates gradient using two colors programmatically.

How to animate arc/donut segment stroke and length change

I need to animate arcs (a.k.a donut segments) in the following scenarios where the arc maintains a constant radius r to the imaginary circle center (the arc sits right outside the circle).
1) Animate the arc stroke width from x to y, while maintaining a radius r and angle alpha.
2) Animate the arc angle from alpha to beta while maintaining a constant stroke width and radius.
3) do 1 and 2 together but possibly with independent animations/timings.
Here's what I have so far:
I’ve implemented the arc drawing as a custom view that simply draws the arc with CGContextAddArc. This is fine for a static arc but it doesn’t animate anything.
Also, I know how to draw clipped images with things like [UIBezierPath addClip].
The latter is interesting because I think that for scenario 1, I can achieve the desired effect in two ways: either keep drawing an arc and modify both stroke and radius to maintain the same perceived inner circle radius (which I’m not optimistic about, I’m afraid that the radius will “jiggle”), or draw a segment of a circle that grows in size (maybe by simply modifying the scale with an affine transform) and is then clipped by a static circular mask.
Now, how do I take all these concepts and nail them down into some actual drawing code? I don’t need real code (though that would be fine too), but more like a conceptual approach, like, can I do this all with a UIView with custom drawing, or do we need to talk about custom key animations that I understand involve CALayers and such. In other words, what’s the right architecture to do all this that would be easiest to code while being efficient from a compositing perspective for smooth animation?
You can already do this with a CAShapeLayer by creating the path for the arc and then animate different stroke properties. You could create the path for the full circle and use the strokeStart and strokeEnd properties to only stroke a certain part of the circle. It is worth noting that the shape layer is center stroked so they increase equally inwards and outwards as you increase the line width. To counter this you could either mask it with the same circle shape and double the line width or animate the path so that the radius increases by half of the line width increase so that the inner most point has the same distance to the center at all times.
The first example can be done by animating the lineWidth property and the second can be done by animating the strokeStart and strokeEnd properties
You should implement this using custom animatable properties on a CALayer subclass. This tutorial (with source here) is for creating animated pie charts and looks pretty good. You should be able to modify it for your requirements.

Resources