Drawing animation

I am creating a simple application where, when the user clicks a button, a series of lines will be drawn on the screen and the user will be able to see these lines in real time (almost like an animation).

My code looks something like this (simplified):

UIGraphicsBeginImageContext(CGSizeMake(300,300)); CGContextRef context = UIGraphicsGetCurrentContext(); for (int i = 0; i < 100; i++ ) { CGContextMoveToPoint(context, i, i); CGContextAddLineToPoint(context, i+20, i+20); CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]); CGContextStrokePath(context); } UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

My problem is that:

1) As soon as the user clicks the button, UIThread is blocked until the drawing is completed.

2) I can not get the lines to be drawn across the screen one at a time - I tried to set UIImage directly inside the loop, and also tried to set the contents of the layer inside the loop.

How do I get around these issues?

+6
source share
1 answer

You say "like animation." Why not make the actual animation, a la Core Graphics' CABasicAnimation ? Do you really need to show this as a series of lines, or is this a good animation?

If you want to animate the actual line drawing, you can do something like:

 #import <QuartzCore/QuartzCore.h> - (void)drawBezierAnimate:(BOOL)animate { UIBezierPath *bezierPath = [self bezierPath]; CAShapeLayer *bezier = [[CAShapeLayer alloc] init]; bezier.path = bezierPath.CGPath; bezier.strokeColor = [UIColor blueColor].CGColor; bezier.fillColor = [UIColor clearColor].CGColor; bezier.lineWidth = 5.0; bezier.strokeStart = 0.0; bezier.strokeEnd = 1.0; [self.view.layer addSublayer:bezier]; if (animate) { CABasicAnimation *animateStrokeEnd = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; animateStrokeEnd.duration = 10.0; animateStrokeEnd.fromValue = [NSNumber numberWithFloat:0.0f]; animateStrokeEnd.toValue = [NSNumber numberWithFloat:1.0f]; [bezier addAnimation:animateStrokeEnd forKey:@"strokeEndAnimation"]; } } 

Then all you have to do is create a UIBezierPath for your string, for example:

 - (UIBezierPath *)bezierPath { UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(0.0, 0.0)]; [path addLineToPoint:CGPointMake(200.0, 200.0)]; return path; } 

If you want, you can fix a bunch of strings in one path, for example. Here is a row of lines with a sinusoidal curve:

 - (UIBezierPath *)bezierPath { UIBezierPath *path = [UIBezierPath bezierPath]; CGPoint point = self.view.center; [path moveToPoint:CGPointMake(0, self.view.frame.size.height / 2.0)]; for (CGFloat f = 0.0; f < M_PI * 2; f += 0.75) { point = CGPointMake(f / (M_PI * 2) * self.view.frame.size.width, sinf(f) * 200.0 + self.view.frame.size.height / 2.0); [path addLineToPoint:point]; } return path; } 

And they do not block the main thread.

By the way, you obviously have to add CoreGraphics.framework to your Build Settings target under Link Binary With Libraries .

+16
source

Source: https://habr.com/ru/post/927294/


All Articles