How to know the current position of a UIImageView moving? - iphone

I have to do a little game where 2 images are moving horizontally on the same line. I want to know when they are superposed, in order to display a new image instead of 2.
What is the best way to do it ?
Way I was thinking to do :
I need to know the position somewhat during the animation of my UIImageViews and I'll try with timer to refresh the imageView when I discover that the 2 imageViews are close.
I have this function so far to move an Image :
- (void)moveImage:(UIImageView *)image duration:(NSTimeInterval)duration
curve:(int)curve x:(CGFloat)x y:(CGFloat)y
{
// Setup the animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationBeginsFromCurrentState:YES];
// The transform matrix
CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
image.transform = transform;
// Commit the changes
[UIView commitAnimations];
}
Thank you for you help !

I think checking the position multiple times every second is not the best way to do it. If you can, you should precalculate the point in time, when the view overlap!
In any way, you shouldn't use the affinetransform for moving the imageview but just moving the frame of the imageview, by changing the frame or the center property of the view!
If you cant precalculate this, here are some tips on how to implement the timer and checking:
For implementing the timer you can use:
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(checkPosition:) userInfo:nil repeats:YES];
This will call the function every 0.1 seconds.
- (void)checkPosition:(NSTimer *)timer
In this method you could access the imageViews UILayer to find out the actual position of this view by calling
CGFrame currentFrame = [imageView.layer presentationLayer].frame;
To be able to do this you have to import the QuartzCore framework!

Related

Animate fade-out for drawings

I have a view where the user can draw. What I want is that, the strokes that were drawn by the user must slowly fade-out in the order that they were drawn. Any advice ?
JYou can try pluging in a AnimationFadeOut and also set a duration to it. Here is a code snippet for that. Let me know if this helps you out.
-(void)fadeOut:(UIView*)viewToDissolve withDuration:(NSTimeInterval)duration andWait:(NSTimeInterval)wait
{
[UIView beginAnimations: #"Fade Out" context:nil];
// wait for time before begin
[UIView setAnimationDelay:wait];
// druation of animation
[UIView setAnimationDuration:duration];
viewToDissolve.alpha = 0.0;
[UIView commitAnimations];
}
Rather than uiview you can use your action to fade out.
For what you're asking, you could simply add a stroke as a subview, then use a cross fade transition.
[drawingView addSubView:strokeView];
[UIView transitionWithView:strokeView duration:0.2f options:UIViewAnimationOptionTransitionCrossDissolve animations:NULL completion:NULL];
For something like this (showing a drawing being completed), I would personally capture the touch points and time offsets to animate the drawing of each point at the speed of the drawer. More code, but a stylistic choice.

Set animation curve

I'm scrolling through a scroll view dynamically, it works using
-(IBAction) animateTestingTwo{
[UIView animateWithDuration:4 animations:^{scroller.contentOffset = CGPointMake(0, 2000);}];
}
However the animation curve is not linear, it needs to be so I'm using this:
-(IBAction) animateTestingTwo{
[UIView animateWithDuration:4 options:UIViewAnimationOptionCurveLinear animations:^{scroller.contentOffset = CGPointMake(0, 2000);}];
}
However it isn't working. Any ideas?
Thanks!!
If the duration doesn't matter to you, this can be used:
[scrollview setContentOffset:CGPointMake(10, 200) animated:YES];
Acconding to the documentation:
animated
YES to animate the transition at a constant velocity to the new offset, NO to make the transition immediate.
You can also try to do this inside an animation block to see what happens.

How to display continously the image position while it is moving?

I want to display the image position while it is animating.
the Animation code is shown here,
[UIImageView beginAnimations:nil context:NULL];
[UIImageView setAnimationDuration:2];
[UIImageView setAnimationRepeatAutoreverses:YES];
[UIImageView setAnimationRepeatCount:20];
CGPoint poss;
poss.x=150;
poss.y=328;
img2.center=poss;
[UIImageView commitAnimations];
Can any one tell me how to display the image position every microsecond in NSLog.
You can set the animation delegate object setAnimationDelegate: for receiving the start- and stop-message from your animation. In that functions you should set a BOOL that you can determine if the animation is still active.
To get the position write a function that would called with the help from an NSTimer, that log the position of your image if the animation is active, otherwise disable the timer.
Hope that helps...?
Put timer function that calls a method having the below line and declare the img2 at class level at every microsecond or while you want to display
[NSTimer scheduledTimerWithTimeInterval:(2/1000000) target:self selector:#selector(Log) userInfo:nil repeats:NO];
-(void)Log {
NSLog(#"X:%f \n Y:%f",img2.center.x,img2.center.y);
}

collision of two images problem

Here is my code :
-(void)collision {
if(CGRectIntersectsRect(ball.frame,center.frame)) {
center.alpha=0.1;
}
}
-(void)viewDidLoad {
[super viewDidLoad];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:7.0f];
[ball setCenter:CGPointMake(200, 100)];
[UIView commitAnimations];
[NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(collision) userInfo:nil repeats:YES];
}
My problem is that when viewDidLoad "center.alpha=0.1" but "center" and "ball" have not collided yet , I don't know why, I think it is due to the animation.
Although the animation takes 7 seconds, [ball setCenter:CGPointMake(200, 100)];is set immediately and because of that - (void)collision probably sets your alpha to 0.1 before "ball" intersects with "center" in the animation.
Instead of UIView animations you could use a NSTimer to slowly change the center of "ball".
You are scheduling the call to collision 0.01 seconds after the line is executed at the end of viewDidLoad. But the view hasn't been displayed yet and so it could take longer than 0.01 seconds to display the view.
Try viewDidAppear
Having said that, I think you are not clear on the purpose of the animtions in iOS. These are not for calculating collision detection - they are just for moving things from a start point to an end point over a set time. I would suggest you read the Apple docs on the animation system.

Moving an object without animating it in an animation block

I'm animating a bunch of buttons so they move to the left of the screen then they should magically move to the right of the screen. I do this by calling:
[NSTimer scheduledTimerWithTimeInterval:0.20 target:self selector:#selector(moveTheButtons) userInfo:nil repeats:YES];
in viewDidLoad.
They animate quite happily to the left, but then they animate back to the right. I just want them to disappear and reappear to the right-off-screen. Because I'm new I assumed that since it was after the commitAnimations call that it wouldn't animate. I think the problem is that the animations actually 'commit' after the moveTheButtons function returns, but I can't think of an elegant (or standard) way around this.
How do I move the UIButton off screen without animating it, preferably still in the moveTheButtons function?
As you can probably infer, I'm new to animations on the iPhone, so if you see any other mistakes I'm making feel free to give me some pointers.
-(void)moveTheButtons{
NSLog(#"moveTheButtons");
[UIView beginAnimations:#"mov-ey" context:cloudA];
[UIView setAnimationDuration: .20];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
cloudA.center = CGPointMake(cloudA.center.x-pos.x,cloudA.center.y);
[UIView commitAnimations];
if(cloudA.center.x < -100){
//I don't want to animate this bit.
cloudA.center = CGPointMake(550,cloudA.center.y);
}
//NSLog(#"cloudA.center.x %f", cloudA.center.x);
}
You can temporarily turn off the implicit animations of properties within an animation block using the +[UIView setAnimationsEnabled:] method. This can be very useful in many use cases.
Do something like this:
-(void)moveTheButtons {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: .20];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
CGPoint center = CGPointMake(cloudA.center.x - pos.x, cloudA.center.y);
if (center.x < -100) {
[UIView setAnimationsEnabled:NO];
cloudA.center = CGPointMake(550, center.y);
[UIView setAnimationsEnabled:YES];
} else {
cloudA.center = center;
}
[UIView commitAnimations];
}
As a side note; there is no need to give the animation a name, or a context, unless you actually use a delegate that responds to delegate methods. Just pass nil, and NULL as I have done in this example.
Precalculate the point , invert the order and return before animating the block.
You are unconditionally committing an animation to the engine in all cases.
-(void)moveTheButtons{
NSLog(#"moveTheButtons");
CGPoint mypoint = CGPointMake(cloudA.center.x-pos.x,cloudA.center.y);
if(cloudA.center.x < -100){
//I don't want to animate this bit.
cloudA.center = CGPointMake(550,cloudA.center.y);
return;
}
[UIView beginAnimations:#"mov-ey" context:cloudA];
[UIView setAnimationDuration: .20];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
cloudA.center = mypoint;
[UIView commitAnimations];
}
Theres a style point about using a return rather than if/else but you can form your own opinion.
Cheers