This question already has an answer here:
How to Animate a UIBezierPath
(1 answer)
Closed 9 years ago.
Is is possible to animate a point of a bezier curve? I am trying make a smooth transition from a line to an arrow.
Here's what the line looks like in code
//// Color Declarations
UIColor* white = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 0.374];
//// Group
{
//// Bezier Drawing
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(30.5, 43.5)];
[bezierPath addLineToPoint: CGPointMake(30.5, 29.59)];
[bezierPath addLineToPoint: CGPointMake(30.5, 15.5)];
bezierPath.lineCapStyle = kCGLineCapRound;
bezierPath.lineJoinStyle = kCGLineJoinBevel;
[white setStroke];
bezierPath.lineWidth = 5.5;
[bezierPath stroke];
}
... however I do not know how to pick a point and animate just that. Is this even possible?
Explicit CGPath animation using a CAShapeLayer:
// Create the starting path. Your curved line.
UIBezierPath * startPath;
// Create the end path. Your straight line.
UIBezierPath * endPath;
// Create the shape layer to display and animate the line.
CAShapeLayer * myLineShapeLayer = [[CAShapeLayer alloc] init];
CABasicAnimation * pathAnimation = [CABasicAnimation animationWithKeyPath:#"path"];
pathAnimation.fromValue = (__bridge id)[startPath CGPath];
pathAnimation.toValue = (__bridge id)[endPath CGPath];
pathAnimation.duration = 5.0f;
[myLineShapeLayer addAnimation:pathAnimation forKey:#"animationKey"];
It isn't clear what you are asking. Are you trying to animate changing the shape of your line by moving one of the control points?
The way to animate changes to paths is to create a CAShapeLayer and install it as a sublayer of your view's layer. Then if you change the path associated with the shape layer the system will use implicit animation to make the change.
Note that the path in the shape layer needs to have the same number/type of control points or the results of the animation are "undefined."
Related
How to create 2 buttons in iOS with custom shapes. I need to draw two buttons like Diagonal of a rectangle. Left side is one button and right side is another button. I've tried using Bezier paths, But how to make them adaptive for all devices ?
Here is my code that I've tried for one button
UIBezierPath* bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 138, 118)];
[UIColor.blackColor setStroke];
bezierPath.lineWidth = 20;
[bezierPath stroke];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = self.Btn.bounds;
shapeLayer.path = bezierPath.CGPath;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.strokeColor = [UIColor blackColor].CGColor;
shapeLayer.lineWidth = 120;
self.Btn.layer.mask = shapeLayer;
cant u just do one button,
subclass it and hittest the CGPoint to determine which shape you should set highlighted/selected/etc
I want to draw a filled sector of a circle using SKShapeNode with UIBezierPath.
I works well in most cases, but with smaller angles the shape is not filled entirely(right under the arc there is a little gap). Like this:
Here is the code I use:
CGPoint center = CGPointMake(500, 300) ;
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath addArcWithCenter:center radius:400 startAngle:1.825777 endAngle:2.011118 clockwise:YES];
[bezierPath addLineToPoint:center];
[bezierPath closePath];
SKShapeNode *shapeNode = [SKShapeNode shapeNodeWithPath:bezierPath.CGPath];
shapeNode.strokeColor = [UIColor whiteColor];
shapeNode.fillColor = [UIColor whiteColor];
[self addChild:shapeNode];
The result is the same on iPad and on the simulator (iOS 8.1).
Am I doing something wrong or it is some limitation or bug?
If it's not possible to draw this shape more accurately with these API, could you please suggest some other ways to draw it in the context of SpriteKit game.
Thank you in advance.
It could be a SKShapeNode bug, see http://sartak.org/2014/03/skshapenode-you-are-dead-to-me.html
One fix, would be to increase the lineWidth of the SKShapeNode so it fills up the gap.
shapeNode.lineWidth = 4
You could instead do the same with UIKit using the same bezierPath and fill and stroke it in drawRect.
I'm trying to draw filled and stroked arc. Please see this image(Left: what i have. Right: what i need]):
I don't know how to set arcs join behaviour. Here is the code(arrowLayer is a CAShapeLayer):
UIBezierPath *arcPath = [UIBezierPath bezierPath];
[arcPath addArcWithCenter:CGPointMake(frame.size.width/2, frame.size.height/2)
radius:65
startAngle:DEGREES_TO_RADIANS(-10)
endAngle:DEGREES_TO_RADIANS(320)
clockwise:YES];
[arcPath addArcWithCenter:CGPointMake(frame.size.width/2, frame.size.height/2)
radius:55
startAngle:DEGREES_TO_RADIANS(-10)
endAngle:DEGREES_TO_RADIANS(320)
clockwise:YES];
arrowLayer.path = [arcPath CGPath];
arrowLayer.fillColor = [UIColor clearColor].CGColor;
arrowLayer.strokeColor = [[UIColor redColor] CGColor];
arrowLayer.lineWidth = 1.0;
Additional Question:
How to get start and end points coords of arc, is it possible? It needs to complete the second part of my task.
I am trying to make a game where a ball is bouncing off a user drawn line. The code for drawing the line is included below and works fine but how would I remove the line once the ball makes contact with it or the player draws a new line?
path = [UIBezierPath bezierPath];
// Start Coords of Line
[path moveToPoint:CGPointMake(pos2x, pos2y)];
[path addLineToPoint:CGPointMake(pos1x, pos1y)];
// End Coords of Line
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [path CGPath];
shapeLayer.strokeColor = [[UIColor whiteColor] CGColor];
shapeLayer.lineWidth = 3.0;
shapeLayer.fillColor = [[UIColor clearColor] CGColor];
[self.view.layer addSublayer:shapeLayer];
Thanks in advance!
When you say this:
[self.view.layer addSublayer:shapeLayer];
...also keep a reference to that shape layer. For example, you might have a property currentShapeLayer:
self.currentShapeLayer = shapeLayer;
Now that you have a reference, you can easily remove the layer:
[self.currentShapeLayer removeFromSuperlayer];
Programming iOS is all about keeping references to things you know you'll need later on. If there are more paths, meaning more shape layers, you will need a more complex, intelligent way of distinguishing which is which and which one you want to remove.
I am trying to draw a view with few hollow circles in it. The view background color will be black with opacity 0.5 and hollow circles on places where I could see the view underneath it. This is working fine with below piece of code but has an issue when my hollow circles intersects, I want to cover both of them as hollow area but due to even odd rule this is not working out. Any suggestions?
Or any alternatives?
- (void)addShadowView {
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height) cornerRadius:0];
for (NSValue *point in self.hollowFrames) {
UIBezierPath *circlePath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(point.CGPointValue.x - self.hollowCircleRadius.floatValue, point.CGPointValue.y - self.hollowCircleRadius.floatValue, 2.0 * self.hollowCircleRadius.floatValue, 2.0 * self.hollowCircleRadius.floatValue) cornerRadius:self.hollowCircleRadius.floatValue];
[path appendPath:circlePath];
}
[path setUsesEvenOddFillRule:YES];
CAShapeLayer *fillLayer = [CAShapeLayer layer];
fillLayer.path = path.CGPath;
fillLayer.fillRule = kCAFillRuleEvenOdd;
fillLayer.fillColor = [UIColor blackColor].CGColor;
fillLayer.opacity = 0.5;
[self.layer addSublayer:fillLayer];
}
This is how it looks right now. I want the intersected area also to be hollow and not filled with the fillColor.
don't fill the circles, clip out the centers.