Delay an animation – Objective-C - iphone

I am using the following code to animate a circle. However, it is constantly blinking. I want to delay the restart of the animation by 5 seconds. How can I do that?
-(void)start
{
[self removeExistingAnimation];
//create the image
UIImage* img = [UIImage imageNamed:#"redCircle.png"];
imageView = [[UIImageView alloc] initWithImage:img];
imageView.frame = CGRectMake(0, 0, 0, 0);
[self addSubview:imageView];
//opacity animation setup
CABasicAnimation *opacityAnimation;
opacityAnimation=[CABasicAnimation animationWithKeyPath:#"opacity"];
opacityAnimation.duration = ANIMATION_DURATION;
opacityAnimation.repeatCount = ANIMATION_REPEAT;
//theAnimation.autoreverses=YES;
opacityAnimation.fromValue = [NSNumber numberWithFloat:0.6];
opacityAnimation.toValue = [NSNumber numberWithFloat:0.025];
//resize animation setup
CABasicAnimation *transformAnimation;
transformAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
transformAnimation.duration = ANIMATION_DURATION;
transformAnimation.repeatCount = ANIMATION_REPEAT;
//transformAnimation.autoreverses=YES;
transformAnimation.fromValue = [NSNumber numberWithFloat:MIN_RATIO];
transformAnimation.toValue = [NSNumber numberWithFloat:MAX_RATIO];
//group the two animation
CAAnimationGroup *group = [CAAnimationGroup animation];
group.repeatCount = ANIMATION_REPEAT;
[group setAnimations:[NSArray arrayWithObjects:opacityAnimation, transformAnimation, nil]];
group.duration = ANIMATION_DURATION;
//apply the grouped animaton
[imageView.layer addAnimation:group forKey:#"groupAnimation"];
}

Do it like this :
-(void)start
{
[self removeExistingAnimation];
//create the image
UIImage* img = [UIImage imageNamed:#"redCircle.png"];
imageView = [[UIImageView alloc] initWithImage:img];
imageView.frame = CGRectMake(0, 0, 0, 0);
[self addSubview:imageView];
[self doAnimation];
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(doAnimation) userInfo:nil repeats:YES];
}
-(void)doAnimation
{
//opacity animation setup
CABasicAnimation *opacityAnimation;
opacityAnimation=[CABasicAnimation animationWithKeyPath:#"opacity"];
opacityAnimation.duration = ANIMATION_DURATION;
opacityAnimation.repeatCount = ANIMATION_REPEAT;
//theAnimation.autoreverses=YES;
opacityAnimation.fromValue = [NSNumber numberWithFloat:0.6];
opacityAnimation.toValue = [NSNumber numberWithFloat:0.025];
//resize animation setup
CABasicAnimation *transformAnimation;
transformAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
transformAnimation.duration = ANIMATION_DURATION;
transformAnimation.repeatCount = ANIMATION_REPEAT;
//transformAnimation.autoreverses=YES;
transformAnimation.fromValue = [NSNumber numberWithFloat:MIN_RATIO];
transformAnimation.toValue = [NSNumber numberWithFloat:MAX_RATIO];
//group the two animation
CAAnimationGroup *group = [CAAnimationGroup animation];
group.repeatCount = ANIMATION_REPEAT;
[group setAnimations:[NSArray arrayWithObjects:opacityAnimation, transformAnimation, nil]];
group.duration = ANIMATION_DURATION;
//apply the grouped animaton
[imageView.layer addAnimation:group forKey:#"groupAnimation"];
}
This is look like dirty method but worked for me , hop it help you..

Isn't this a bit cleaner? Or is there a reason why you can't use blocks for animating?
- (void) start {
//create the image
UIImage* img = [UIImage imageNamed:#"redCircle.png"];
imageView = [[UIImageView alloc] initWithImage:img];
[self addSubview:imageView];
[self animateWithDelay:0.0];
}
- (void) animateWithDelay:(CGFloat)delay {
imageView.alpha = 0.0;
imageView.transfrom = CGAffineTransformScale(myImage.transform, MIN_RATIO, MIN_RATIO);
[UIImageView animateWithDuration:ANIMATION_DURATION delay:delay options:0 animations:^{
imageView.alpha = 1.0;
imageView.transfrom = CGAffineTransformScale(myImage.transform, MAX_RATIO, MAX_RATIO);
} completion:^{
animationCount++;
if (ANIMATION_REPEAT != animationCount) {
[self animateWithDelay:5.0];
}
}];
}
You should define animationCount somewhere in your class, so you know when he should stop repeating.
(Not tested, so could contain some errors)

Related

Why is this only fading In and not fading out

I have an image on the UIButton that I wish to glow in when I click button and glow out when I click it again.
Everytime I click, it doesn't glow out, it only glows in making it brighter
.
I have tried UIView animateWithDuration as well as CATransition and CABasicAnimation..
Something is wrong. Probably something basic that I should know about.
I'd appreciate the help.
Heres my code:
-(void)didTapButton:(UIButton *)button {
button.selected = !button.selected;
UIColor *glowColor = [self.arrayOfGlowColor objectAtIndex:button.tag];
UIImageView *imageView = button.imageView;
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, [UIScreen mainScreen].scale);
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0,0,imageView.bounds.size.width,imageView.bounds.size.height)];
[glowColor setFill];
[path fillWithBlendMode:kCGBlendModeSourceAtop alpha:1.0];
UIImage *imageContext_image = UIGraphicsGetImageFromCurrentImageContext();
UIView *glowView = [[UIImageView alloc] initWithImage:imageContext_image];
glowView.center = imageView.center;
[imageView.superview insertSubview:glowView aboveSubview:imageView];
glowView.alpha = 0;
glowView.layer.shadowColor = glowColor.CGColor;
glowView.layer.shadowOffset = CGSizeZero;
glowView.layer.shadowRadius = 10;
glowView.layer.shadowOpacity = 1.0;
/*
[UIView animateWithDuration: 1.0 animations:^(void) {
glowView.alpha = (button.selected) ? 1.0 : 0.0f;
}];
NSLog(#"glowView.alpha:%f",glowView.alpha);
NSLog(button.selected ? #"YES" : #"NO");
*/
/*
if (button.selected) {
CATransition *fadeIn = [CATransition animation];
fadeIn.duration = 1.0;
fadeIn.startProgress = 0.0f;
fadeIn.endProgress = 1.0f;
[fadeIn setType:kCATransitionFade];
fadeIn.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[fadeIn setFillMode:#"extended"];
[glowView.layer addAnimation:fadeIn forKey:nil];
}
if (!button.selected) {
CATransition *fadeOut = [CATransition animation];
fadeOut.duration = 1.0;
fadeOut.startProgress = 1.0f;
fadeOut.endProgress = 0.0f;
[fadeOut setType:kCATransitionFade];
fadeOut.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[fadeOut setFillMode:#"extended"];
[glowView.layer addAnimation:fadeOut forKey:nil];
}
*/
if (button.selected) {
//Create a one-way animation that fades in the glow.
glowView.layer.opacity = 1.0;
CABasicAnimation *glowFadeInAnim = [CABasicAnimation animationWithKeyPath:#"opacity"];
glowFadeInAnim.fromValue = [NSNumber numberWithDouble:0.0];
glowFadeInAnim.toValue = [NSNumber numberWithDouble:1.0];
glowFadeInAnim.repeatCount = 1;
glowFadeInAnim.duration = 1.0;
glowFadeInAnim.autoreverses = FALSE;
glowFadeInAnim.fillMode = kCAFillModeForwards;
glowFadeInAnim.removedOnCompletion = NO;
glowFadeInAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[glowView.layer addAnimation:glowFadeInAnim forKey:nil];
}
if (!button.selected) {
glowView.layer.opacity = 1.0;
CABasicAnimation *glowFadeOutAnim = [CABasicAnimation animationWithKeyPath:#"opacity"];
glowFadeOutAnim.fromValue = [NSNumber numberWithDouble:1.0];
glowFadeOutAnim.toValue = [NSNumber numberWithDouble:0.0];
glowFadeOutAnim.repeatCount = 1;
glowFadeOutAnim.beginTime = 2;
glowFadeOutAnim.duration = 2.0;
glowFadeOutAnim.autoreverses = FALSE;
glowFadeOutAnim.fillMode = kCAFillModeForwards;
glowFadeOutAnim.removedOnCompletion = NO;
glowFadeOutAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[glowView.layer addAnimation:glowFadeOutAnim forKey:nil];
glowView.layer.opacity = 0.0;
}
NSLog(#"glowView.opacity:%f",glowView.layer.opacity);
NSLog(button.selected ? #"YES" : #"NO");
}
If you create a new glowView every time the button is pressed and add it to the button, then obviously it will just keep getting brighter, as more and more of them are being added to the button. You need to create the glowView once, for example in your viewDidLoad method, and store it as an instance variable so you don't lose it:
#interface MyViewController : UIViewController {
UIView *_glowView;
}
...
- (void)viewDidLoad {
[super viewDidLoad];
_glowView = ... // Initialise it here
...
[imageView.superview insertSubview:_glowView aboveSubview:imageView];
}
Then in your didTapButton: method, you handle the tap as you do (adding or removing the _glowView, but make sure you don't set it to nil so the reference to it is always retained). This way, you only create and add it once, and the problem should be solved.

Can't click on UIButton (that appears programmatically) after animation gets done

Just had a small question. I'm trying to make a UIButton appear programmatically, which I have to animate. But once the animation gets done, I can't click the button for some reason.
I have a CALayer "animationLayer" as a sublayer of the UIView, and within that animationLayer, I have three CAShapeLayers "pathLayers" (which I use to animate three different path ways as you can see in the diagram below). And within those pathLayers, I'm adding three buttons as their respective sublayers so that I can have an animation where the buttons move along the path as the path draws itself. Everything was working good until I tried adding a button as a sublayer of the pathLayer. Now when I click on the button, it's supposed to go to a method that logs on the console window "Button has been pressed". I've tried setting the self.view.userInteractionenabled to YES but that still gives me nothing.
Why I can't click it?
Here's some relevant parts of the code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.animationLayer = [CALayer layer];
self.animationLayer.frame = CGRectMake(20.0f, 64.0f,
CGRectGetWidth(self.view.layer.bounds) - 40.0f, CGRectGetHeight(self.view.layer.bounds) - 84.0f);
[self.view.layer addSublayer:self.animationLayer];
}
- (id)createUIButtonwithXPosition:(CGFloat)x YPosition:(CGFloat)y Width:(CGFloat)width Height:(CGFloat)height
{
UIImage *lionImage = [UIImage imageNamed:#"noun_project_347_2.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(logger:)
forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(x, y, width, height);
button.userInteractionEnabled = YES;
// [button setBackgroundColor:[UIColor clearColor]];
[button setBackgroundImage:lionImage forState:UIControlStateNormal];
[self.view addSubview:button];
return button;
}
- (void)setupDrawingLayer
{
if(self.pathLayer != nil){
[self.pathLayer removeFromSuperlayer];
[self.secondPathLayer removeFromSuperlayer];
[self.thirdPathLayer removeFromSuperlayer];
self.pathLayer = nil;
self.secondPathLayer = nil;
self.thirdPathLayer = nil;
...//Other code not relevant
}
CGRect pathRect = CGRectInset(self.animationLayer.bounds, 100.0f, 100.0f);
CGPoint bottomCenter = CGPointMake(CGRectGetMidX(pathRect), (self.lionBtnVerticalAlignment.constant + self.lionBtnHeight.constant + 25.0f));
CGPoint center = CGPointMake(CGRectGetMidX(pathRect), CGRectGetMidY(pathRect));
CGPoint leftCenter = CGPointMake(CGRectGetMinX(pathRect), CGRectGetMidY(pathRect));
CGPoint rightCenter = CGPointMake(CGRectGetMaxX(pathRect), CGRectGetMidY(pathRect));
UIBezierPath *path = [UIBezierPath bezierPath];
UIBezierPath *secondPath = [UIBezierPath bezierPath];
UIBezierPath *thirdPath = [UIBezierPath bezierPath];
[path moveToPoint:bottomCenter];
[path addLineToPoint:center];
[secondPath moveToPoint:bottomCenter];
[secondPath addLineToPoint:leftCenter];
[thirdPath moveToPoint:bottomCenter];
[thirdPath addLineToPoint:rightCenter];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.frame = self.animationLayer.bounds;
pathLayer.bounds = pathRect;
pathLayer.geometryFlipped = YES;
pathLayer.path = path.CGPath;
pathLayer.strokeColor = [UIColor blackColor].CGColor;
pathLayer.fillColor = nil;
pathLayer.lineWidth = 3.0f;
pathLayer.lineDashPattern = [NSArray arrayWithObjects:
[NSNumber numberWithInt:6],
[NSNumber numberWithInt:2],
nil];
pathLayer.lineJoin = kCALineJoinBevel;
CAShapeLayer *secondPathLayer = [CAShapeLayer layer];
secondPathLayer.frame = self.animationLayer.bounds;
secondPathLayer.bounds = pathRect;
secondPathLayer.geometryFlipped = YES;
secondPathLayer.path = secondPath.CGPath;
secondPathLayer.strokeColor = [UIColor redColor].CGColor;
secondPathLayer.fillColor = nil;
secondPathLayer.lineWidth = 3.0f;
secondPathLayer.lineDashPattern = [NSArray arrayWithObjects:
[NSNumber numberWithInt:6],
[NSNumber numberWithInt:2],
nil];
secondPathLayer.lineJoin = kCALineJoinBevel;
CAShapeLayer *thirdPathLayer = [CAShapeLayer layer];
thirdPathLayer.frame = self.animationLayer.bounds;
thirdPathLayer.bounds = pathRect;
thirdPathLayer.geometryFlipped = YES;
thirdPathLayer.path = thirdPath.CGPath;
thirdPathLayer.strokeColor = [UIColor greenColor].CGColor;
thirdPathLayer.fillColor = nil;
thirdPathLayer.lineWidth = 3.0f;
thirdPathLayer.lineDashPattern = [NSArray arrayWithObjects:
[NSNumber numberWithInt:6],
[NSNumber numberWithInt:2],
nil];
thirdPathLayer.lineJoin = kCALineJoinBevel;
[self.animationLayer addSublayer:pathLayer];
[self.animationLayer addSublayer:secondPathLayer];
[self.animationLayer addSublayer:thirdPathLayer];
self.pathLayer = pathLayer;
self.secondPathLayer = secondPathLayer;
self.thirdPathLayer = thirdPathLayer;
UIImage *lionImage = [UIImage imageNamed:#"noun_project_347_2.png"];
btn1 = (UIButton *)[self createUIButtonwithXPosition:0.0f YPosition:0.0f Width:lionImage.size.width Height:lionImage.size.height];
btn1.layer.anchorPoint = CGPointZero;
btn1.layer.frame = CGRectMake(0.0f, 0.0f, lionImage.size.width, lionImage.size.height);
[self.view bringSubviewToFront:btn1];
self.view.userInteractionEnabled = YES;
....//Other code not relevant
}
- (void)startAnimation
{
[self.pathLayer removeAllAnimations];
[self.secondPathLayer removeAllAnimations];
[self.thirdPathLayer removeAllAnimations];
....//Other code not relevant
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
pathAnimation.duration = 3.0;
pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
[self.pathLayer addAnimation:pathAnimation forKey:#"strokeEnd"];
[self.secondPathLayer addAnimation:pathAnimation forKey:#"strokeEnd"];
[self.thirdPathLayer addAnimation:pathAnimation forKey:#"strokeEnd"];
CAKeyframeAnimation *lionAnimation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
lionAnimation.duration=3.0;
lionAnimation.path = self.pathLayer.path;
lionAnimation.calculationMode = kCAAnimationPaced;
lionAnimation.delegate = self;
[btn1.layer addAnimation:lionAnimation forKey:#"position"];
btn1.layer.position = CGPointMake(365.0, 460.0);
}
Seems to me that you might be experiencing a typical problem in which a UIView is a sub child of another UIView, but outside of its bounds. To check whether this is the case, set the property of the parentview to setClipsToBounds:YES and you will most likely see the button disappear. Check this post for additional details: My custom UIView dos not receive touches
If this is the case you have a couple of options.
Place the button in a place where it is within the bounds of the parent view!!
Subclass the parent view and add the following code to is so that its subviews may respond to touches even when they are outside the bounds of the parent view.
-(UIView *) hitTest:(CGPoint)point withEvent:(UIEvent *)event{
UIView* result = [super hitTest:point withEvent:event];
if (result)
return result;
for (UIView* sub in [self.subviews reverseObjectEnumerator]) {
CGPoint pt = [self convertPoint:point toView:sub];
result = [sub hitTest:pt withEvent:event];
if (result)
return result;
}
return nil;
}
Please try this:
[button setBackgroundImage:lionImage forState:UIControlEventTouchUpInside];

Iphone-How do I get an image to rotate continously for about 60 seconds and then stop in the other direction

I need the image to spin around a few times and come to a stop in the opposite dirrection. THe image is a button with arrow that points right and then it spins a few times and comes to a stop facing the other way. Any help will be appreciated.
This is what I have at the moment.
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.duration = 0.60;//animation.duration = 0.60;
animation.repeatCount = 1;//animation.repeatCount = 1000ˆ
//#warning remove comment brackets below
animation.keyTimes = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:1.0], nil];
animation.values = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:(degrees / 180)*M_PI], nil];
animation.fillMode = kCAFillModeForwards;
Please try this and let me know. This is working for me.
UIImageView *tempView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 80, 80)];
tempView.image = [UIImage imageNamed:#"Icon"];
tempView.backgroundColor = [UIColor redColor];
[self.view addSubview:tempView];
const NSUInteger rotations = 10;
const NSTimeInterval duration = 5;
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:#"transform.rotation"];
CGFloat touchUpStartAngle = 0;
CGFloat touchUpEndAngle = (M_PI);
CGFloat angularVelocity = (((2 * M_PI) * rotations) + M_PI) / duration;
anim.values = #[#(touchUpStartAngle), #(touchUpStartAngle + angularVelocity * duration)];
anim.duration = duration;
anim.autoreverses = NO;
anim.delegate = self;
anim.repeatCount = 1;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[tempView.layer addAnimation:anim forKey:#"test"];
tempView.transform = CGAffineTransformMakeRotation(touchUpStartAngle + (touchUpEndAngle));
The following code works for me. It actually doesn´t change the direction. I think you can achieve this by adding a timer which change the imagesArray.
First I also tried using CAKeyframeAnimation like you but I couldn´t figure it out. So I changed to an animating image - I thought this way couldn´t be too bad, because Apple e.g. use this way also for animating the activity indicator.
-(void) myImageInitFunction {
UIImage *icon = [UIImage imageNamed:#"yourIconImage"];
NSArray *imagesArray = rotatingImagesArrayOfImage(icon, 30);
myImageViewThatShouldRotate.animationImages = imageArray;
myImageViewThatShouldRotate.animationDuration= 2.0;
[myImageViewThatShouldRotate startAnimating];
}
NSArray *rotatingImagesArrayOfImage(UIImage * icon, NSInteger nFrames)
{
NSMutableArray *images = [NSMutableArray arrayWithObject:icon];
for (NSInteger nLoop = 1; nLoop < nFrames; nLoop++) {
[images addObject: [UIImage imageWithCGImage: CGImageRotatedByAngle(icon.CGImage, nLoop * ( 360 / nFrames)) ] ];
}
return images;
}
CGImageRef CGImageRotatedByAngle(CGImageRef imgRef, CGFloat angle) {
CGFloat angleInRadians = angle * (M_PI / 180);
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGRect imgRect = CGRectMake(0, 0, width, height);
CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bmContext = CGBitmapContextCreate(NULL,
rotatedRect.size.width,
rotatedRect.size.height,
8,
0,
colorSpace,
kCGImageAlphaPremultipliedFirst);
CGContextSetAllowsAntialiasing(bmContext, YES);
CGContextSetShouldAntialias(bmContext, YES);
CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh);
CGColorSpaceRelease(colorSpace);
CGContextTranslateCTM(bmContext,
+(rotatedRect.size.width/2),
+(rotatedRect.size.height/2));
CGContextRotateCTM(bmContext, angleInRadians);
CGContextTranslateCTM(bmContext,
-(rotatedRect.size.width/2),
-(rotatedRect.size.height/2));
CGContextDrawImage(bmContext, CGRectMake(0, 0,
rotatedRect.size.width,
rotatedRect.size.height),
imgRef);
CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
CFRelease(bmContext);
return rotatedImage;
}
i use this:
- (void)startAnimations {
CABasicAnimation* spinAnimation = [CABasicAnimation
animationWithKeyPath:#"transform.rotation"];
spinAnimation.toValue = [NSNumber numberWithFloat:M_PI];
spinAnimation.cumulative = YES;
spinAnimation.duration = 0.5;
spinAnimation.repeatCount = 10000;
[imageView.layer addAnimation:spinAnimation forKey:#"spinAnimation"];
}
- (void)cancelAnimations {
[imageView.layer removeAnimationForKey:#"spinAnimation"];
imageView.transform = CGAffineTransformMakeRotation(0.0);
}
call a timer in start animations to call cancelanimations in 60 secs. you can make rotation angle whatever you want
Thanks everyone this page is now very resourceful.
This is another solution.
- (CAKeyframeAnimation *)rotateFrom:(CGFloat)fromDegrees to:(CGFloat)toDegrees {
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.delegate = self;
animation.duration = 0.30;
animation.repeatCount = 1;
animation.keyTimes = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:1.0], nil];
animation.values= [NSArray arrayWithObjects:
[NSNumber numberWithFloat:fromDegrees*(M_PI/180)],
[NSNumber numberWithFloat:toDegrees*(M_PI/180)], nil];
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
return animation;
}

Stop animation when same time remove button from superview

if i tap on button then this button is animate with rotation and add once again in self.view, but i want to when this button is add in view more than 10 in self.view then remove first button, and next animation is not stop, i want to remove button in another thread, but not effect on animation
I Try that code for another thread, but not work properly, animation is stop
-(void)putFruietAtOriginPositionInMainThread:(NSDictionary*)btnDictionary{
//if (!dragFlag) {
[self playSoundEffect:#"abc.mp3" withRepeatCount:0];
//[self.view bringSubviewToFront:btnBag];
//[self.view bringSubviewToFront:bagView];
UIButton *btnFruiet = [btnDictionary objectForKey:#"btnFruiet"];
int position= [[btnDictionary objectForKey:#"position"]intValue];
CGFloat xPosition = [[[dicCenterPoint objectForKey:[NSString stringWithFormat:#"%i",btnFruiet.tag]] objectAtIndex:0]floatValue];
CGFloat yPosition = [[[dicCenterPoint objectForKey:[NSString stringWithFormat:#"%i",btnFruiet.tag]] objectAtIndex:1]floatValue];
btnFruiet.center = self.view.center;
//btnFruiet.enabled = FALSE;
//[self playSoundEffect:#"shapes_collapse.mp3" withRepeatCount:0];
if ([dicFruitTimer count]>0) {
NSTimer *timer = [dicFruitTimer valueForKey:[NSString stringWithFormat:#"%i",btnFruiet.tag]];
if (timer) {
[timer invalidate];
timer=nil;
[dicFruitTimer removeObjectForKey:[NSString stringWithFormat:#"%i",btnFruiet.tag]];
}
}
NSTimer *fruitTimer = [NSTimer timerWithTimeInterval:0.00002 target:self selector:#selector(setFrameOfFruietWithTimer:) userInfo:[NSDictionary dictionaryWithObject:btnFruiet forKey:#"fruit"] repeats:YES];
[[NSRunLoop mainRunLoop]addTimer:fruitTimer forMode:NSRunLoopCommonModes];
[dicFruitTimer setObject:fruitTimer forKey:[NSString stringWithFormat:#"%i",btnFruiet.tag]];
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:FRUIT_ANIMATION_DURATION/2] forKey:kCATransactionAnimationDuration];
CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
CGMutablePathRef positionPath = CGPathCreateMutable();
CGPathMoveToPoint(positionPath, NULL, [btnFruiet layer].position.x , [btnFruiet layer].position.y);
CGPathAddLineToPoint(positionPath, NULL, xPosition, yPosition);
positionAnimation.path = positionPath;
//CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
// rotateAnimation.delegate = self;
// //rotateAnimation.autoreverses = YES;
// rotateAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
// rotateAnimation.fromValue = [NSNumber numberWithFloat:2.0];
// rotateAnimation.toValue = [NSNumber numberWithFloat:1.0];
// rotateAnimation.fillMode = kCAFillModeForwards;
// rotateAnimation.removedOnCompletion = NO;
CABasicAnimation *shrinkAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
shrinkAnimation.fromValue = [NSNumber numberWithFloat:kScaleFactor];
shrinkAnimation.toValue = [NSNumber numberWithFloat:1.0f];
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
theGroup.delegate = self;
theGroup.removedOnCompletion = NO;
theGroup.fillMode = kCAFillModeForwards;
theGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
theGroup.animations = [NSArray arrayWithObjects:positionAnimation, shrinkAnimation,nil];
NSString *strPosition = [NSString stringWithFormat:#"%d,3", position];
[theGroup setValue:strPosition forKey:#"AnimationGroup"];
[[btnFruiet layer] addAnimation:theGroup forKey:#"AnimationGroup"];
//btnAnimationRunning = btnFruiet;
[CATransaction commit];
CGPathRelease(positionPath);
//[arrTimers removeObject:timer];
//}
if ([arrFruitOnScreen count]>10) {
//NSThread *thread = [[NSThread alloc] init];
//[self performSelector:#selector(removeFruit) withObject:nil];
[self performSelector:#selector(removeFruit) withObject:nil afterDelay:FRUIT_ANIMATION_DURATION/2];
//[thread start];
//[self performSelector:#selector(removeFruit) onThread:thread withObject:nil waitUntilDone:NO];
//}
}
-(void)removeFruit{
UIButton *btnF = [arrFruitOnScreen objectAtIndex:0];
[[btnF layer] removeAllAnimations];
[arrFruitOnScreen removeObjectAtIndex:0];
[btnF removeFromSuperview];
}
It's pretty unclear what you're trying to achieve but UIKit updates must be done in the main thread. This should address the part where it doesn't work on another thread.

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");
}