I am drawing jigsaw using CAShapeLayer.Drawing a line that is easy part and also i did it.But now i want to draw ellipse with cutting some portion of that ellipse.Now my question is how can i cut ellipse using CGPathAddEllipseInRect?Here is my code :
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
[shapeLayer setBounds:self.bounds];
[shapeLayer setPosition:self.center];
[shapeLayer setFillColor:[[UIColor clearColor] CGColor]];
[shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]];
[shapeLayer setLineWidth:3.0f];
// Setup the path
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 10, 10);
CGPathAddLineToPoint(path, NULL, 75,10);
CGPathAddEllipseInRect(path, NULL, CGRectMake(75, 10, 50, 20));
[shapeLayer setPath:path];
CGPathRelease(path);
[[self layer] addSublayer:shapeLayer];
Hint will be appreciated.
Don't use CGPathAddEllipseInRect, instead you need to calculate the start and end positions and use CGPathAddArcToPoint or, more likely, CGPathAddQuadCurveToPoint.
Related
I have one UIView with size 141 X 161. Then I created a circle .Here is that code:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CAShapeLayer *circleLayer = [CAShapeLayer layer];
[circleLayer setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 86, 79)] CGPath]];
[[self.photoView layer] addSublayer:circleLayer];
[circleLayer setStrokeColor:[[UIColor blackColor] CGColor]];
[circleLayer setFillColor:[[UIColor clearColor] CGColor]];
}
photoview is my uiview
When I run it's not in centre,
I need my circle in perfect centre of inside my UIView ( 141 x 161). And also need to set outside border.
And my circle is think.how to set radius at 1.
And my circle fill should be #222222
Border: thickness = 1.9
color = white
position = centre
I am new to iOS.
Try this :
CAShapeLayer *circleLayer = [CAShapeLayer layer];
[circleLayer setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(27, 41, 86, 79)] CGPath]];
[[self.photoView layer] addSublayer:circleLayer];
[circleLayer setStrokeColor:[[UIColor whiteColor] CGColor]];
[circleLayer setFillColor:[[UIColor clearColor] CGColor]];
circleLayer.lineWidth = 0.5;
circleLayer.shadowColor = [UIColor whiteColor].CGColor;
circleLayer.shadowOpacity = 0.4;
circleLayer.borderColor = [UIColor whiteColor] .CGColor;
circleLayer.borderWidth = 2;
circleLayer.fillColor =[UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.25].CGColor;
circleLayer.borderColor = [[UIColor whiteColor] CGColor];
I want to draw a circle in iOS. It can be an image view or view, I want to adjust its size on gestures. Like, dragging from outside to the center, the radius of the circle should reduce and so vice versa.
Please note that I want to fix the position of that view, circle or image. I just want to adjust the size as it is dragged.
try this
- (IBAction)pinch:(UIPinchGestureRecognizer *)sender {
double scale=[sender scale];
self.view1.frame=CGRectMake(self.view1.frame.origin.x*scale, self.view1.frame.origin.y*scale, self.view1.frame.size.width*scale, self.view1.frame.size.height*scale);
[self.view1.layer setCornerRadius:5];
}
Try this.
- (IBAction)pan:(UIPanGestureRecognizer *)sender {
for (CALayer *layer in self.imageView.layer.sublayers) {
[layer removeFromSuperlayer];
}
CGPoint scale =[sender locationInView:sender.view];
CAShapeLayer *circleLayer = [CAShapeLayer layer];
[circleLayer setBounds:CGRectMake(0.0f, 0.0f, [_imageView bounds].size.width,
[_imageView bounds].size.height)];
[circleLayer setPosition:CGPointMake(CGRectGetMidX([_imageView bounds]),CGRectGetMidY([_imageView bounds]))];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, CGRectGetWidth(_imageView.frame)+scale.x, CGRectGetHeight(_imageView.frame)+scale.y)];
[circleLayer setPath:[path CGPath]];
[circleLayer setStrokeColor:[[UIColor redColor] CGColor]];
[circleLayer setLineWidth:1.0f];
[circleLayer setFillColor:[[UIColor clearColor] CGColor]];
[[_imageView layer] addSublayer:circleLayer];
}
I've created an arc at a 12 o'clock position on a CAShapeLayer and added it as a sublayer onto a UIView. The arc is rough or bumpy. I tried antialiasing, corner radius, line join, and have also tried rasterizing at one point but no luck. Any ideas why it's not smooth and what to do to make it smoother? If make the same arc at 9 or 3 o'clock they are smooth, but not 12 or 6 o'clock. Appreciate any help.
Here's the code:
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddArc(path, nil, 38.25, 38.25, 25, degreesToRadians(304), degreesToRadians(236), YES);
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
[shapeLayer setAllowsEdgeAntialiasing:YES];
[shapeLayer setEdgeAntialiasingMask:kCALayerLeftEdge | kCALayerRightEdge | kCALayerBottomEdge | kCALayerTopEdge];
[shapeLayer setCornerRadius:2.0];
[shapeLayer setLineJoin:kCALineJoinRound];
[shapeLayer setFillColor:[[UIColor clearColor] CGColor]];
[shapeLayer setStrokeColor:[color CGColor]];
[shapeLayer setLineCap:kCALineCapRound];
[shapeLayer setLineWidth:3.0];
[shapeLayer setPath:path];
Here's a link to the arcs. Top and bottom are not smooth like on the left. They look less smooth on a device. Screen capture sort of smoothed them out more than they actually are.
http://oi57.tinypic.com/2wf4i9c.jpg
It looks like your layer is off the pixel bounds. That is, it’s rasterizing the layer, then shifting it by a fractional number of pixels before drawing. My first suggestion would be to round those x.25 values to whole numbers.
By the way, why are you passing 304, 236 as the startAngle and endAngle in CGPathAddArc()? Those parameters are in radians, not degrees.
edgeAntialiasingMask and allowsEdgeAntialiasing has to do with how the edges of the layer’s rectangular bounds are rendered, and should not affect the contents.
Edit: the difference is subtle, but when I stop using fractional values, the slight bumps in the line go away. By the way, if you post your images in .png format, it’s easier to see what’s going on, because they don’t get the artifacting from jpg compression.
// Fractional values
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddArc(path, nil, 138.25, 138.25, 25, degreesToRadians(304), degreesToRadians(236), YES);
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
[shapeLayer setLineJoin:kCALineJoinRound];
[shapeLayer setFillColor:[[UIColor clearColor] CGColor]];
[shapeLayer setStrokeColor:[UIColor blueColor].CGColor];
[shapeLayer setLineCap:kCALineCapRound];
[shapeLayer setLineWidth:3.0];
[shapeLayer setPath:path];
CGPathRelease(path);
[self.view.layer addSublayer:shapeLayer];
// Integral values
CGMutablePathRef newPath = CGPathCreateMutable();
CGPathAddArc(newPath, nil, 200, 138, 25, degreesToRadians(304), degreesToRadians(236), YES);
CAShapeLayer *newShapeLayer = [CAShapeLayer layer];
[newShapeLayer setLineJoin:kCALineJoinRound];
[newShapeLayer setFillColor:[[UIColor clearColor] CGColor]];
[newShapeLayer setStrokeColor:[UIColor blueColor].CGColor];
[newShapeLayer setLineCap:kCALineCapRound];
[newShapeLayer setLineWidth:3.0];
[newShapeLayer setPath:newPath];
CGPathRelease(newPath);
[self.view.layer addSublayer:newShapeLayer];
And the result:
When I overlay them in Difference Mode in Photoshop, you can see where the pixels differ:
I am trying to add inner shadow on few UITextField and UITextView. I have set cornerRadius property for these controls to 1.0. and I am using the code which is mentioned below to create the inner shadow. But problem is that the shadow appears with the steep rectangular corners while the text view and the text field are with rounded corners.
I am calling following method in my viewcontroller class to add the shadow on my text field.
[self addInnerShadow:myTextField.frame];
- (void)addInnerShadow:(CGRect)frame
{
CAShapeLayer* shadowLayer = [CAShapeLayer layer];
[shadowLayer setFrame:frame];
[shadowLayer setShadowColor:[[UIColor blackColor] CGColor]];
[shadowLayer setShadowOffset:CGSizeMake(0.0f, 0.0f)];
[shadowLayer setShadowOpacity:1.0f];
[shadowLayer setShadowRadius:5];
[shadowLayer setFillRule:kCAFillRuleEvenOdd];
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectInset(CGRectMake(0, 0, frame.size.width, frame.size.height),-5, -5));
CGMutablePathRef someInnerPath = CGPathCreateMutable();
CGPathAddRect(someInnerPath, NULL, CGRectInset(CGRectMake(0, 0, frame.size.width, frame.size.height), 0, 0));
CGPathAddPath(path, NULL, someInnerPath);
CGPathCloseSubpath(path);
[shadowLayer setPath:path];
CGPathRelease(path);
CAShapeLayer* maskLayer = [CAShapeLayer layer];
[maskLayer setPath:someInnerPath];
[shadowLayer setMask:maskLayer];
[[self.view layer] addSublayer:shadowLayer];
}
This
CGContextRef context = UIGraphicsGetCurrentContext();
// Shadow
UIColor* shadow4 = [[UIColor blackColor] colorWithAlphaComponent: 0.81];
CGSize shadow4Offset = CGSizeMake(0.1, 2.1);
CGFloat shadow4BlurRadius = 5;
UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(20.5, 26.5, 200, 40) cornerRadius: 4];
[[UIColor whiteColor] setFill];
[rectanglePath fill];
CGRect rectangleBorderRect = CGRectInset([rectanglePath bounds], -shadow4BlurRadius, - shadow4BlurRadius);
rectangleBorderRect = CGRectOffset(rectangleBorderRect, -shadow4Offset.width, - shadow4Offset.height);
rectangleBorderRect = CGRectInset(CGRectUnion(rectangleBorderRect, [rectanglePath bounds]), -1, -1);
UIBezierPath* rectangleNegativePath = [UIBezierPath bezierPathWithRect: rectangleBorderRect];
[rectangleNegativePath appendPath: rectanglePath];
rectangleNegativePath.usesEvenOddFillRule = YES;
CGContextSaveGState(context);
{
CGFloat xOffset = shadow4Offset.width + round(rectangleBorderRect.size.width);
CGFloat yOffset = shadow4Offset.height;
CGContextSetShadowWithColor(context,
CGSizeMake(xOffset + copysign(0.1, xOffset), yOffset + copysign(0.1, yOffset)),
shadow4BlurRadius,
shadow4.CGColor);
[rectanglePath addClip];
CGAffineTransform transform = CGAffineTransformMakeTranslation(-round(rectangleBorderRect.size.width), 0);
[rectangleNegativePath applyTransform: transform];
[[UIColor grayColor] setFill];
[rectangleNegativePath fill];
}
CGContextRestoreGState(context);
[[UIColor blackColor] setStroke];
rectanglePath.lineWidth = 0.5;
[rectanglePath stroke];
Will produce this. You can manipulate this to get your desired effect.
Create path with UIBezierPath
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:frame
byRoundingCorners:UIRectCornerAllCorners
cornerRadii:CGSizeMake(5.0, 5.0)];
And than use it with Layer.
I am using this code to draw a circle inside a UIImageView.
CAShapeLayer *circleLayer = [CAShapeLayer layer];
// Give the layer the same bounds as your image view
[circleLayer setBounds:CGRectMake(0.0f, 0.0f, [photoView bounds].size.width,
[photoView bounds].size.height)];
// Position the circle anywhere you like, but this will center it
// In the parent layer, which will be your image view's root layer
[circleLayer setPosition:CGPointMake(coordsFinal.x + 130, coordsFinal.y + 200)];
// Create a circle path.
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:
CGRectMake(0.0f, 0.0f, 50.0f, 50.0f)];
// Set the path on the layer
[circleLayer setPath:[path CGPath]];
// Set the stroke color
[circleLayer setStrokeColor:[color CGColor]];
// Set the stroke line width
[circleLayer setLineWidth:2.0f];
// Add the sublayer to the image view's layer tree
[[photoView layer] addSublayer:circleLayer];
I would like the circle to be empty, and to have only the border. How can I remove the fill?
Set the fill color to transparent (alpha 0)
[circleLayer setFillColor:[[UIColor colorWithWhite:0 alpha:0] CGColor]];
AKA...
[circleLayer setFillColor:[[UIColor clearColor] CGColor]];
(thanks Zev)
The CAShapeLayer manual page explicitly says set fillColor to nil to perform no fill operation. That is not the same as filling with a transparent color, which some have suggested doing, as the latter will overwrite existing contents making them clear/transparent, and should be considered a destructive operation.