问题
In my app I have this code in viewWillAppear. It simply animates random object from top of the screen to the bottom. The problem is I need to detect collision and what I have learnt so far is it is impossible to retrieve the coordinates at any time for an animation. so how can I implement it by using NSTimer? or shall I use NSTimer? I could not figure it out. Any clue will be appreciated.
-(void)viewWillAppear:(BOOL)animated
{
for (int i = 0; i < 100; i++) {
p = arc4random_uniform(320)%4+1;
CGRect startFrame = CGRectMake(p*50, -50, 50, 50);
CGRect endFrame = CGRectMake(p*50, CGRectGetHeight(self.view.bounds) + 50,
50,
50);
animatedView = [[UIView alloc] initWithFrame:startFrame];
animatedView.backgroundColor = [UIColor redColor];
[self.view addSubview:animatedView];
[UIView animateWithDuration:2.f
delay:i * 0.5f
options:UIViewAnimationCurveLinear
animations:^{
animatedView.frame = endFrame;
} completion:^(BOOL finished) {
[animatedView removeFromSuperview];
}];
}
回答1:
Your statement:
is it is impossible to retrieve the coordinates at any time for an animation
seems incorrect did you check this?
It looks like you can use the CALayer's presentationLayer
property to extract coordinates info during an animation:
CGRect movingFrame = [[yourView.layer presentationLayer] frame];
I will use this info to check time to time if there is a collision during the animation. So I will use the timer to check the collision status not for animating the views.
回答2:
I would ditch NSTimer
for CADisplayLink
to send a message to your target. NSTimer
can cause stuttering animations since it doesn't synchronize with the device's screen refresh rate. CADisplayLink
does exactly that and makes your animations run like butter.
Documentation: http://developer.apple.com/library/ios/#documentation/QuartzCore/Reference/CADisplayLink_ClassRef/Reference/Reference.html
Ultimately, using CADisplayLink
looks something like this:
- (id) init {
// ...
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
// ...
}
- (void) update {
[myView updatePositionOrSomethingElse];
}
回答3:
You can have your objects animate in small increments (in a loop may be). Every time you complete your animation, you can get the coordinates.
回答4:
I think you could use the beginAnimations - commitAnimations syntax in a for cycle it could count for eg. till 10, so after each cycle you can check for collision
CGRect incrementedViewFrame;
for(int i = 0; i < 10; ++i)
{
incrementedViewFrame = CGRectMake(/*calculate the coords here*/);
if(collision)
{
//do stuff
}
else
{
//do an other animation cycle
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.1f];
[[self viewToAnimate]setFrame:incrementedViewFrame];
[UIView commitAnimations];
}
}
I hope that helps!
来源:https://stackoverflow.com/questions/12139675/iphone-development-how-to-create-an-animation-by-using-nstimer