I have a CAShapeLayer with an opaque stroke and a transparent fill. I then want to call myContext.drawRadialGradient, but have this radial gradient clip to the stroke of my shape layer. Currently, I'm calling myShapeLayer.path.addClip(), which clips the radial gradient to the fill region of the shape layer, instead of the stroke.
In other words, I'd like to use either just the opaque part of a layer or just the stroke (same thing in my case), and use it to clip the current context. I've been searching the CoreGraphics docs for a while to no avail.
Found my answer. You can create a new UIBezierPath that is a copy of your existing one, with a stroke, as below:
let strokePath = UIBezierPath(cgPath: oldPath.cgPath.copy(
strokingWithWidth: ..., lineCap: ..., lineJoin: ..., miterLimit: ...))
strokePath.addClip()
What if you add your shape layer as the mask of your gradient layer? That should work, since that's what a mask layer is supposed to do.
If that doesn't work you might need to capture your shape layer to an image and install THAT as the mask of your gradient layer.
Convert the stroked path to a new path whose fill area is the same as the original stroke. Now you have a fillable area that you can use as clipping area. The CGContext way to do this is by calling replacePathWithStrokedPath. As the docs explicitly say:
For example, you can clip to the stroked version of a path by calling this function followed by a call to the function clip().
Related
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.
I have drawn a path on a view, All I need is to apply a gradient blur effect from the outer edge of the closed drawn path to the view's bounds. My question is mainly about the Gradient blur effect rather than applying it on the path.
I've not tried this but believe you could make it work:
create the path
use the path as a mask can create an new image that is clear outside the path while selecting the interior of the path (the interior has to be opaque)
use a radial blur on the whole image
composite the saved interior path OVER the blurred image
stroke the path to get a clear definition between the original interior and the blurred exterior
I am drawing ellipse using following UIBezierPath method:
UIBezierPath *bpath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(x, y, width, height)];
This gives me something like below:
But I want to draw ellipse at an angle like below:
I know one solution is to rotate the UIView. But I cannot do this because same view contain other bezier paths. So I want to know if there is any way to draw this ellipse at an angle?
Often the easiest way is to put this on a CAShapeLayer and then rotate the layer. The math for that tends to be very simple (particularly if you want to change the transform later). But you can also just rotate the path directly before drawing it by creating a rotation transform (CGAffineTransformMakeRotation) and using -applyTransform: to modify the path.
I have downloaded the new Facebook messanger App for iOS. I was wondering, is there some option that allows to "crop" an image and leave only a circle?
Would be great to be able to put a UIImage which is rectangular and crop the circular part.
Or do you think this is done server-side? In other words, there is no special iOS cropping function but simply a cropping software on the Facebook server?
use
imageView.layer.cornerRadius=imageView.frame.size.width/2.0;
imageView.clipsToBounds=YES;
This is actually quite easy to do.
What you want to do is to create a CAShapeLayer the same size as your view. Create a UIBezierPath that uses a rounded rectangle who's corner radius is 1/2 the height/width. That gives you a circular path.
Install the bezier path's CGPath into the shape layer. Then set the shape layer to fill with an opaque color.
Finally, install the shape layer as the mask on your view's layer. The result is that the shape layer clips the view and only shows the opaque parts of the shape layer.
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.