How to add CALayer rect shape on AVCapture video? - iphone

I want to display a CALayer on video captured by AVCapture.
I am able to display the layer but for the next frame the previous should be removed.
My code is:
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
for (int i = 0; i < faces.size(); i++) {
CGRect faceRect;
// Get the Graphics Context
faceRect.origin.x = xyPoints.x;
faceRect.origin.y = xyPoints.y;
faceRect.size.width =50; //faces[i].width;
faceRect.size.height =50;// faces[i].height;
CALayer *featureLayer=nil;
// faceRect = CGRectApplyAffineTransform(faceRect, t);
if (!featureLayer) {
featureLayer = [[CALayer alloc]init];
featureLayer.borderColor = [[UIColor redColor] CGColor];
featureLayer.borderWidth = 10.0f;
[self.view.layer addSublayer:featureLayer];
}
featureLayer.frame = faceRect;
NSLog(#"frame-x - %f, frame-y - %f, frame-width - %f, frame-height - %f",featureLayer.frame.origin.x,featureLayer.frame.origin.y,featureLayer.frame.size.width,featureLayer.frame.size.height);
}
// [featureLayer removeFromSuperlayer];
[CATransaction commit];
where face is (const std::vector<cv::Rect)face OpenCV format.
I need to know where to place the code [featureLayer removeFromSuperLayer];
Note: "face" is not for face detection... it is just a rectangle.

I have got the solution ...
featureLayer is CALayer object I gave this as identity. Like
featureLayer.name = #"earLayer";
and whenever I detect the Object in frame I get the sublayers from main view like
NSArray *sublayers = [NSArray arrayWithArray:[self.view.layer sublayers]];
and count the sublayer to check in for loop like below:
int sublayersCount = [sublayers count];
int currentSublayer = 0;
for (CALayer *layer in sublayers) {
NSString *layerName = [layer name];
if ([layerName isEqualToString:#"earayer"])
[layer setHidden:YES];
}
Now I am getting the proper layer with Detected objects.

Related

How to detect and show eyes and mouth in camera in iPhone?

For detecting face in camera I am reffering to SquareCam(iOS developer library). But I am unable to show left eye, right eye and mouth position. I am using the following code
NSArray *sublayers = [NSArray arrayWithArray:[previewLayer sublayers]];
NSInteger sublayersCount = [sublayers count], currentSublayer = 0;
NSInteger featuresCount = [features count], currentFeature = 0;
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
// hide all the face layers
for ( CALayer *layer in sublayers )
{
if ( [[layer name] isEqualToString:#"FaceView"] )
[layer setHidden:YES];
}
if ( featuresCount == 0 || !detectFaces ) {
[CATransaction commit];
return; // early bail.
}
CGSize parentFrameSize = [previewView frame].size;
NSString *gravity = [previewLayer videoGravity];
BOOL isMirrored = [previewLayer isMirrored];
CGRect previewBox = [SquareCamViewController videoPreviewBoxForGravity:gravity
frameSize:parentFrameSize
apertureSize:clap.size];
for ( CIFaceFeature *ff in features ) {
// find the correct position for the square layer within the previewLayer
// the feature box originates in the bottom left of the video frame.
// (Bottom right if mirroring is turned on)
CGRect faceRect = [ff bounds];
CGRect leftEyeFrameRect;
CGFloat temp = faceRect.size.width;
faceRect.size.width = faceRect.size.height;
faceRect.size.height = temp;
temp = faceRect.origin.x;
faceRect.origin.x = faceRect.origin.y;
faceRect.origin.y = temp;
// scale coordinates so they fit in the preview box, which may be scaled
CGFloat widthScaleBy = previewBox.size.width / clap.size.height;
CGFloat heightScaleBy = previewBox.size.height / clap.size.width;
faceRect.size.width *= widthScaleBy;
faceRect.size.height *= heightScaleBy;
faceRect.origin.x *= widthScaleBy;
faceRect.origin.y *= heightScaleBy;
if ( isMirrored )
{
faceRect = CGRectOffset(faceRect, previewBox.origin.x + previewBox.size.width - faceRect.size.width - (faceRect.origin.x * 2), previewBox.origin.y);
}
else
{
faceRect = CGRectOffset(faceRect, previewBox.origin.x, previewBox.origin.y);
leftEyeFrameRect=CGRectOffset(faceRect,ff.leftEyePosition.x, ff.leftEyePosition.y);
}
CALayer *featureLayer = nil;
CALayer *eyeLayer = nil;
// re-use an existing layer if possible
while ( !featureLayer && (currentSublayer < sublayersCount) )
{
CALayer *currentLayer = [sublayers objectAtIndex:currentSublayer++];
if ( [[currentLayer name] isEqualToString:#"FaceLayer"] ) {
featureLayer = currentLayer;
[currentLayer setHidden:NO];
}
}
// create a new one if necessary
if ( !featureLayer ) {
featureLayer = [CALayer new];
[featureLayer setContents:(id)[square CGImage]];
[featureLayer setName:#"FaceLayer"];
[previewLayer addSublayer:featureLayer];
[featureLayer release];
}
[featureLayer setFrame:faceRect];
if (faceView !=nil) {
[faceView removeFromSuperview];
[faceView release];
}
if (leftEyeView != nil) {
[leftEyeView removeFromSuperview];
[leftEyeView release];
}
faceView = [[UIView alloc] initWithFrame:CGRectMake(faceRect.origin.x, faceRect.origin.y ,faceRect.size.width, faceRect.size.height)];
faceView.layer.borderWidth = 1;
faceView.layer.borderColor = [[UIColor redColor] CGColor];
[self.view addSubview:faceView];
leftEyeView = [[UIView alloc] initWithFrame:CGRectMake(faceView.frame.origin.x+(faceView.frame.size.height/2), faceView.frame.origin.y+(faceView.frame.size.height*0.10) ,faceView.frame.size.width*0.40, faceView.frame.size.height*0.40)];
UIImageView *leftEyeImageView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"eye.png"]];
leftEyeImageView.frame = CGRectMake(0, 0, faceView.frame.size.width*0.40, faceView.frame.size.height*0.40);
[leftEyeView addSubview:leftEyeImageView];
[self.view addSubview:leftEyeView];
if (ff.hasLeftEyePosition) {
CGPoint leftEyeCenter= ff.leftEyePosition;
UIView *vv= [[UIView alloc] initWithFrame:CGRectMake(leftEyeCenter.x, leftEyeCenter.y, 50, 50)];
vv.center = leftEyeCenter;
vv.layer.borderWidth= 4.0;
vv.layer.borderColor= [[UIColor blackColor]CGColor];
[self.view addSubview:vv];
}
It is detecting eye but not showing in right position. Can anyone help to resolve this.
Thanks in advance.
I faced the same problem as you in the preview when using the front camera, because the preview is mirrored and I could not find any good information to scale.
The following code is the closest I got. Please note that I have an image defined as property that is called heartImage and that I assume you are using the Apple Sample called SquareCam.
In the method - (void)drawFaceBoxesForFeatures:(NSArray *)features forVideoBox:(CGRect)clap orientation:(UIDeviceOrientation)orientation
if(ff.hasLeftEyePosition)
{
//swap coordinates
CGFloat leftEyeRectOriginX = ff.leftEyePosition.y ;
CGFloat leftEyeRectOriginY = ff.leftEyePosition.x ;
CGFloat leftEyeRectWidth = faceRect.size.width*0.3;
CGFloat leftEyeRectHeight = faceRect.size.width*0.3;
//adjust scale
leftEyeRectOriginX *= widthScaleBy;
leftEyeRectOriginY *= heightScaleBy;
NSLog(#"LeftEyePosition: %#", NSStringFromCGPoint(ff.leftEyePosition));
CGRect r = CGRectMake(leftEyeRectOriginX - (leftEyeRectWidth/2) , leftEyeRectOriginY - (leftEyeRectHeight/2), leftEyeRectWidth, leftEyeRectHeight);
if ( isMirrored ){
r = CGRectOffset(r, previewBox.origin.x + previewBox.size.width - (rightEyeRectOriginX*2) - rightEyeRectWidth+ faceRect.origin.x, previewBox.origin.y);
NSLog(#"LeftEyeRect mirrored: %#", NSStringFromCGRect(r));
}
else{
r = CGRectOffset(r, previewBox.origin.x, previewBox.origin.y);
}
while ( !leftEyeEyeLayer && (currentSublayer < sublayersCount) ) {
CALayer *currentLayer = [sublayers objectAtIndex:currentSublayer++];
if ( [[currentLayer name] isEqualToString:#"LeftEyeLayer"] ) {
leftEyeEyeLayer = currentLayer;
[currentLayer setHidden:NO];
}
}
// create a new one if necessary
if ( !leftEyeEyeLayer ) {
leftEyeEyeLayer = [CALayer new];
[leftEyeEyeLayer setContents:(id)[heartImage CGImage]];
[leftEyeEyeLayer setName:#"LeftEyeLayer"];
[previewLayer addSublayer:leftEyeEyeLayer];
[leftEyeEyeLayer release];
}
[leftEyeEyeLayer setFrame:r];
}
The same applies for the Right Eye, with the exception that I use this in case it's mirrored: r = CGRectOffset(r, previewBox.origin.x + previewBox.size.width - (rightEyeRectOriginX*2) - rightEyeRectWidth+ faceRect.origin.x, previewBox.origin.y);
.
The only difference with the sample code is that you first want to remove all the featureLayers, so some lines above my code looks like this:
// hide all the face layers
for ( CALayer *layer in sublayers ) {
if ( [[layer name] isEqualToString:#"FaceLayer"] || [[layer name] isEqualToString:#"LeftEyeLayer"] || [[layer name] isEqualToString:#"RightEyeLayer"] )
[layer setHidden:YES];
}
To be precise, I have troubles only in the live camera preview. When using the method to save picture in library (- (CGImageRef)newSquareOverlayedImageForFeatures:(NSArray *)features
inCGImage:(CGImageRef)backgroundImage
withOrientation:(UIDeviceOrientation)orientation
frontFacing:(BOOL)isFrontFacing
) it works correctly by using:
if(ff.hasLeftEyePosition)
{
CGRect r = CGRectMake(ff.leftEyePosition.x-faceWidth*0.15, ff.leftEyePosition.y-faceWidth*0.15, faceWidth*0.3, faceWidth*0.3);
CGContextDrawImage(bitmapContext, r, [rotatedHeartImage CGImage]);
}
Please let me know if and how I should improve my answer.
This is probably caused by incorrect orientations between your input, detector and output. If the faces are detected, then probably only the output coordinates need to be translated from landscape to portrait or vice versa. Otherwise, take a look here.
You could investigate in Haar cascade training files and OPENGL but that's a total different approuch. It does support iOS versions below 6.0 that's a pro. But it's way harder then the Squarecam sample of Apple (con).
This OpenGL was able to detect ears, eyes etc. There could already be some training files on the web.

Animating the drawing of a line

I'm trying to animate the drawing of a line by the following way:
.h
CAShapeLayer *rootLayer;
CAShapeLayer *lineLayer;
CGMutablePathRef path;
.m
path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, self.frame.size.width/2-100, 260);
CGPathAddLineToPoint(path, nil, self.frame.size.width/2+100.0, 260);
CGPathCloseSubpath(path);
self.rootLayer = [CALayer layer];
rootLayer.frame = self.bounds;
[self.layer addSublayer:rootLayer];
self.lineLayer = [CAShapeLayer layer];
[lineLayer setPath:path];
[lineLayer setFillColor:[UIColor redColor].CGColor];
[lineLayer setStrokeColor:[UIColor blueColor].CGColor];
[lineLayer setLineWidth:1.5];
[lineLayer setFillRule:kCAFillRuleNonZero];
[rootLayer addSublayer:lineLayer];
[self performSelector:#selector(startTotalLine) withObject:nil afterDelay:1.5];
- (void)startTotalLine
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"animatePath"];
[animation setDuration:3.5];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[animation setAutoreverses:NO];
[animation setFromValue:(id)path];
[animation setToValue:(id)path];
[lineLayer addAnimation:animation forKey:#"animatePath"];
}
The line had drawn before the startTotalLine method is invoked.
Also, the startTotalLine method doesn't affect the line.
I want it to animate the the line drawing from right to left.
I would do it with an animated property.
To achieve this I would create a custom CALayer class - let's call it LineLayer. Define a startPoint property, and a length property. I'd then configure the length property to be "animatable".
The code for that would look something like the following:
// LineLayer.h
#interface LineLayer: CALayer
#property (nonatomic, assign) int length;
// This was omitted from the SO code snippet.
#property (nonatomic, assign) CGPoint startPoint;
#end
// LineLayer.m
#implementation LineLayer
#synthesize length = _length;
// This was omitted from the SO code snippet.
#synthesize startPoint= _startPoint;
- (id) initWithLayer:(id)layer
{
if(self = [super initWithLayer:layer])
{
if([layer isKindOfClass:[LineLayer class]])
{
// This bit is required for when we CA is interpolating the values.
LineLayer *other = (LineLayer*)layer;
self.length = other.length;
self.startPoint = other.startPoint; // This was omitted.
}
}
return self;
}
+ (BOOL)needsDisplayForKey:(NSString *)key
{
if ([key isEqualToString:#"length"]) {
return YES;
}
return [super needsDisplayForKey:key];
}
- (void) setLength:(int)newLength
{
if (newLength < 0) {
return; // Fail early.
}
_length = newLength;
[self setNeedsDisplay];
}
/*
This should have been drawInContext:(CGContextRef)context
- (void) drawRect:(CGRect) rect
*/
- (void) drawInContext:(CGContextRef)context
{
//...Do your regular drawing here.
// This was omitted from the SO code snippet.
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, 2);
CGContextMoveToPoint(context, _startPoint.x, _startPoint.y);
CGContextAddLineToPoint(context, _startPoint.x + _length, _startPoint.y);
CGContextStrokePath(context);
}
#end
Then in your view controller you could use LineLayer like this:
- (void)viewDidLoad
{
[super viewDidLoad];
LineLayer *lineLayer = [LineLayer new];
// This was omitted from the SO code snippet.
lineLayer.frame = CGRectMake(0, 0, 320, 480);
[lineLayer setNeedsDisplay];
// ---
lineLayer.startPoint = CGPointMake(0, 100);
lineLayer.length = 0;
[self.view.layer addSublayer:lineLayer];
// Now animate the changes to the length property
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:#"length"];
anim.duration = 5; // Change should table about 5 mins.
anim.fromValue = [NSNumber numberWithInt:0];
anim.toValue = [NSNumber numberWithInt:200];
[lineLayer addAnimation:anim forKey:#"animateLength"];
lineLayer.length = 200;
//Do clean up below...
}
Happy Coding :)
I think the easiest way to do what you want, is to present some UIView that is 1.5 pixel height and animate it's width. Ask me if I'm not clear.
I think your code doesn't work because your variable path is not a layer property. Read manuals:
CABasicAnimation provides basic, single-keyframe animation
capabilities for a layer property.
And you do something strange here:
[animation setFromValue:(id)path];
[animation setToValue:(id)path];
EDIT:
I stumbled upon an article, and understood what you were try to achieve! Now I think the reason you failed is that you can animate path that doesn't change number of points. And now I thought you can create a path-line with two points. At first they are at same place and another path is the line you want to end up with. Now animate from first path to the second. I think it should work, but I'm not sure.
EDIT:
Definitely! You need this guy's code. Git link.
Here is my solution for your case using "UIBezierPath", "CAShapeLayer" and the property "strokeEnd":
.m file
#synthesize shapeLayer;
[self drawLine];
-(void)drawLine {
CGFloat X1 = self.frame.size.width/2-100;
CGFloat Y1 = 260;
CGFloat X2 = self.frame.size.width/2+100.0;
CGFloat Y2 = 260;
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(X1, Y1)];
[path addLineToPoint:CGPointMake(X2, Y2)];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [path CGPath];
shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
shapeLayer.lineWidth = 1.5;
shapeLayer.fillColor = [[UIColor redColor] CGColor];
shapeLayer.strokeEnd =0;
[self.layer addSublayer:shapeLayer];
[self performSelector:#selector(startTotalLine) withObject:nil afterDelay:1.5];
}
- (void)startTotalLine {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
animation.duration = 3.5f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[animation setAutoreverses:NO];
[animation setFromValue:[NSNumber numberWithInt:0]];
[animation setToValue:[NSNumber numberWithInt:1]];
[shapeLayer addAnimation:animation forKey:#"animatePath"];
}
The default "strokeEnd" value is 1, so, make it 0 at the beginning (no line will appear). Btw, here is useful examples provided: http://jamesonquave.com/blog/fun-with-cashapelayer/

animate point multiple times and more naturally

so my current version looks like this: Animation Movie
i'm fairly new to core-animations, so what i try to achieve is that there are multiple points like the current one, moving from the left box in various angles, heights and speeds out of it, just like a tennis ball machine.
the first problem is, that my "ball" doesn't look like it gets grabbed from gravity and also the speed at first is not fast enough.
also, how to do this animation multiple times with variating distances between the beginning.
if something is unclear, PLEASE leave a comment.
my current code:
- (void)loadView {
[super loadView];
self.view.backgroundColor = [UIColor lightGrayColor];
CGPoint startPoint = CGPointMake(20, 300);
CGPoint endPoint = CGPointMake(300, 500);
UIBezierPath *trackPath = [UIBezierPath bezierPath];
[trackPath moveToPoint:startPoint];
[trackPath addQuadCurveToPoint:endPoint controlPoint:CGPointMake(endPoint.x, startPoint.y)];
CALayer *point = [CALayer layer];
point.bounds = CGRectMake(0, 0, 20.0, 20.0);
point.position = startPoint;
point.contents = (id)([UIImage imageNamed:#"point.png"].CGImage);
[self.view.layer addSublayer:point];
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:#"position"];
anim.path = trackPath.CGPath;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
anim.repeatCount = HUGE_VALF;
anim.duration = 2.0;
[point addAnimation:anim forKey:#"movepoint"];
CALayer *caseLayer = [CALayer layer];
caseLayer.bounds = CGRectMake(0, 0, 140.0, 150.0);
caseLayer.position = startPoint;
caseLayer.contents = (id)([UIImage imageNamed:#"case.png"].CGImage);
[self.view.layer addSublayer:caseLayer];
}
Easiest way to model gravity is with those parabolic equations that you learn in basic physics. In short, the function below takes an initial position, a speed, and an angle (IN RADIANS, where 0 is to the right). a CALayer appears at position and gets shot at that speed and angle.
I'm using a CADisplayLink (which is effectively a timer that synchronizes with your frame rate) to call a function very quickly. Every time the function is called, the point is moved. The horizontal speed is constant and the vertical speed increases towards the bottom every frame to emulate gravity (`vy -= 0.5f; ). If you want more/less gravity, just mess around with this 0.5f value.
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
point = [[CALayer alloc] init];
point.bounds = CGRectMake(0.0f, 0.0f, 10.0f, 10.0f);
point.backgroundColor = [UIColor redColor].CGColor;
point.position = CGPointMake(-10.0f, -10.0f);
[self.layer addSublayer:point];
[point release];
}
return self;
}
-(void)animateBallFrom:(CGPoint)start withSpeed:(CGFloat)speed andAngle:(CGFloat)angle
vx = speed*cos(angle);
vy = speed*sin(angle);
[CATransaction begin];
[CATransaction setDisableActions:YES];
point.position = start;
[CATransaction commit];
displayLink = [CADisplayLink displayLinkWithTarget:self selector:#selector(animate)];
[displayLink setFrameInterval:2];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
-(void)animate {
if (point.position.x + point.bounds.size.width/2.0f < 0.0f || point.position.x > self.bounds.size.width + point.bounds.size.width/2.0f ||
point.position.y + point.bounds.size.height/2.0f < 0.0f || point.position.y > self.bounds.size.height + point.bounds.size.height/2.0f) {
[displayLink invalidate];
} else {
[CATransaction begin];
[CATransaction setDisableActions:YES];
point.position = CGPointMake(point.position.x+vx, point.position.y-vy);
vy -= 0.5f;
[CATransaction commit];
}
}
and the interface:
#interface Bounce : UIView {
CALayer *point;
CADisplayLink *displayLink;
CGFloat vx, vy;
}
-(void)animateBallFrom:(CGPoint)start withSpeed:(CGFloat)speed andAngle:(CGFloat)angle;
#end
I think there may be a couple of things you can do here.
- One is to use kCAMediaTimingFunctionLinear instead of kCAMediaTimingFunctionEaseOut.
- The other is to set your control point in the center of the ball's fall, wherever that may be. Try this:
CGPoint startPoint = CGPointMake(20, 300);
CGPoint controlPoint = CGPointMake(160, 400);
CGPoint endPoint = CGPointMake(300, 500);
UIBezierPath *trackPath = [UIBezierPath bezierPath];
[trackPath moveToPoint:startPoint];
[trackPath addQuadCurveToPoint:endPoint controlPoint:controlPoint];
CALayer *point = [CALayer layer];
point.bounds = CGRectMake(0, 0, 20.0, 20.0);
point.position = startPoint;
point.contents = (id)([UIImage imageNamed:#"point.png"].CGImage);
[self.view.layer addSublayer:point];
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:#"position"];
anim.path = trackPath.CGPath;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
anim.repeatCount = HUGE_VALF;
anim.duration = 2.0;
[point addAnimation:anim forKey:#"movepoint"];
You should then be able to move the control point around for different paths.

how to get frame of the image while animating from top to bottom of screen using CABasic animation

I am using CABasicAnimation for animating an image from top to bottom of the screen. I need to
get frame of the image while it is animating from top to bottom......
Code:
-(id)init
{
if(self = [super init])
{
self.title =#"Apple Catch";
mView = [[UIView alloc]initWithFrame:CGRectMake(0,0,320,440)];
// start a timet that will fire 20 times per second
[NSTimer scheduledTimerWithTimeInterval:(0.9) target:self selector:#selector(onTimer)
userInfo:nil repeats:YES];
self.view=mView;
}
return self;
}
- (void)onTimer
{
CGImageRef imageRef = [[UIImage imageNamed:#"apple.png"] CGImage];
int startX = round(random() % 460);
double speed = 1 / round(random() %100) + 1.0;
CALayer *layer = [CALayer layer];
layer.name = #"layer";
layer.contents = imageRef;
layer.frame = CGRectMake(startX, self.view.frame.origin.y, CGImageGetWidth(imageRef),
CGImageGetHeight(imageRef));
[mView.layer addSublayer:layer];
CGPoint start = CGPointMake(startX, 0);
CGPoint end = CGPointMake(startX, self.view.frame.size.height+10);
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"position"];
animation.delegate = self;
animation.fromValue = [NSValue valueWithCGPoint:start];
animation.toValue = [NSValue valueWithCGPoint:end];
animation.duration = 10*speed;
//animation.repeatCount = repeatCount;
animation.autoreverses = NO;
animation.removedOnCompletion = YES;
animation.fillMode = kCAFillModeForwards;
[layer addAnimation:animation forKey:#"position"];
BOOL intersects = CGRectIntersectsRect(layer.frame , dragger.frame);
printf("\n ==== intersects value :%d",intersects);
}
I need the frame of the image that is animating at each point of it's path on the view.
Can u please suggest the code for this.
Thank U
Use the presentationLayer property of the CALayer to which the animation is applied.
Hi friend
you can try if (CGRectIntersectsRect(layer.frame,dragger.frame) ) {
nslog(#"hiiii");
}

Animate the drawing of lines in UIView

Can anybody please help me with this problem? I have the nsarray of lines and I need to write them one after the other within some UIView (I want to animate the hand drawing).
Here is the answer (found here : http://soulwithmobiletechnology.blogspot.fr/2012/07/how-to-animate-line-draw.html)
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(50.0,0.0)];
[path addLineToPoint:CGPointMake(120.0, 600.0)];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.frame = self.view.bounds;
pathLayer.path = path.CGPath;
pathLayer.strokeColor = [[UIColor redColor] CGColor];
pathLayer.fillColor = nil;
pathLayer.lineWidth = 2.0f;
pathLayer.lineJoin = kCALineJoinBevel;
[self.view.layer addSublayer:pathLayer];
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
pathAnimation.duration = 2.0;
pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
[pathLayer addAnimation:pathAnimation forKey:#"strokeEnd"];
Do not forget to #import <QuartzCore/QuartzCore.h>.
Some entry points that might help :
Apple documentations: Core Animation, Quartz 2D and Quartz Demo Sample code
Some Core Animation samples
this code animates an object over a set of points. can use same idea for your lines, which i assume are CGPath?
//
// animate along a set of points
//
// NSLog(#"The content of movement1PointsArray is%#",movement1PointsArray);
CGMutablePathRef touchPath1 = CGPathCreateMutable();
CGPoint touchPath1StartPoint = [[movement1PointsArray objectAtIndex:0] CGPointValue];
CGPathMoveToPoint(touchPath1,NULL,touchPath1StartPoint.x, touchPath1StartPoint.y);
for (NSInteger p = 0; p < [movement1PointsArray count]; ++p)
{
CGPoint touchesPointOnPath = [[movement1PointsArray objectAtIndex:p] CGPointValue];
CGPathAddLineToPoint(touchPath1, NULL,touchesPointOnPath.x,touchesPointOnPath.y);
}
CAKeyframeAnimation* touchPathAnimation1 = [CAKeyframeAnimation animationWithKeyPath:#"position"];
[touchPathAnimation1 setDuration: 1.0];
[touchPathAnimation1 setAutoreverses: NO];
touchPathAnimation1.removedOnCompletion = NO;
touchPathAnimation1.fillMode = kCAFillModeForwards;
[touchPathAnimation1 setPath: touchPath1];
CFRelease(touchPath1);
[animationsArray addObject:touchPathAnimation1];
[ball.layer addAnimation: touchPathAnimation1 forKey: #"position"];
i am having trouble getting a second path to animate...regardless of what i try, it only animates the last path.
You probably end up implementing the views drawRect method.
This http://howtomakeiphoneapps.com/2009/08/how-to-draw-shapes-with-core-graphics/
Should get you started