gpt4 book ai didi

iphone - 当对象已经处于动画状态时,如何更改其动画?

转载 作者:行者123 更新时间:2023-12-03 20:06:05 24 4
gpt4 key购买 nike

所以,现在我有一个火箭,它在 iPhone 5 屏幕底部左右弹跳。然而,我希望火箭停止左右移动,而是在用户触摸屏幕后向上移动(因此触摸屏幕会使火箭起飞)。

首先,在 viewDidAppear 中,我告诉编译器在 2 秒后运行 spawnRocket 方法。

spawnRocket 方法中,我建立了火箭图像和框架,然后将其添加到 View 中并执行 uiview 动画,将火箭发送到屏幕右侧。在 uiview 动画方法的 finished 参数中,我告诉编译器运行 moveRocketLeft 方法。

在 moveRocketLeft 方法中,我制作了一个动画,将火箭发送到屏幕左侧,并在 finished 参数中运行了 moveRocketRight 方法。

moveRocketMethod 基本上是spawnRocket 方法,只是我没有建立火箭图像和框架并将其添加到 View 中。

所以在这一切之后,我尝试实现 -touchesBegan:withEvent: 方法。我尝试简单地运行一个 uiview 动画,将火箭 y 更改为向上离开屏幕,并将 x 更改为用户触摸屏幕时当前 x 所在的位置。

但是,我意识到调用火箭框架不会返回火箭在动画时看起来的位置。它实际上只是返回动画完成后火箭框架的样子。那么,要获得我想要的框架,我应该调用layer吗?我记得在某处读过该层将在动画期间返回 uiimageview 的实际位置。但是,图层只有属性边界,没有框架,所以我有点困惑。

我还尝试调用[self.view.layer removeAllAnimations];,然后运行一个新的动画,这会导致尴尬,但是removeAllAnimations方法从未起作用(无论如何,我不太喜欢使用它的想法,因为我听说它滞后)。

那么有人知道我如何实现 touchesBegan:withEvent: 方法以便火箭能够正确起飞吗? (或者如果您认为我必须更改整个程序,请随时提供帮助)

    #import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface ViewController ()
@property UIImageView *rocket;
@end

@implementation ViewController


@synthesize rocket=_rocket;

- (void)viewDidLoad
{
[super viewDidLoad];

}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view.layer removeAllAnimations];
// [UIView animateWithDuration:3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^(){self.rocket.frame=CGRectMake(self.rocket.frame.origin.x, -40, 25, 40);} completion:^(BOOL finished){}];

// this didn't work :(
}



-(void)viewDidAppear:(BOOL)animated{
[self performSelector:@selector(spawnRocket) withObject:self afterDelay:2];
}
-(void)spawnRocket{
self.rocket=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"default.png"]]; //places imageview right off screen
self.rocket.frame=CGRectMake(-25, 420, 25, 40);

[self.view addSubview:self.rocket];
[UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^(){self.rocket.frame=CGRectMake(295, 420, 25, 40);} completion:^(BOOL finished){if (finished)[self moveRocketLeft]; }];


}

-(void) moveRocketLeft{
[UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^(){self.rocket.frame=CGRectMake(0, 420, 25, 40);} completion:^(BOOL finished){if (finished)[self moveRocketRight];}];
}

-(void)moveRocketRight{
[UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^(){self.rocket.frame=CGRectMake(295, 420, 25, 40);} completion:^(BOOL finished){if (finished)[self moveRocketLeft];}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

最佳答案

这应该可以解决问题

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
CALayer *rocketPresentationLayer = [self.rocket.layer presentationLayer];
self.rocket.layer.position = rocketPresentationLayer.position;
[UIView animateWithDuration:3 delay:0 options:UIViewAnimationOptionCurveEaseIn|UIViewAnimationOptionBeginFromCurrentState animations:^(){self.rocket.frame=CGRectMake(self.rocket.frame.origin.x, -40, 25, 40);} completion:^(BOOL finished){}];
}

注1:我没有在这里放置逻辑来检查用户在火箭垂直起飞时是否再次点击火箭。您可能想添加一个 BOOL 或其他内容来查看用户是否成功击中火箭,如果是,则不再执行垂直动画。

注解 2:如果将来您只想在火箭被击中时发生这种情况,您可以使用 hitTest 检查来有条件地调用动画。

// Get the touch
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self.view];

// See if we hit the rocket
CALayer *rocketPresentationLayer = [self.rocket.layer presentationLayer];
CALayer* hitTest = [rocketPresentationLayer hitTest:touchPoint];

// If we did, then stop animation and move upwards
if (hitTest) {
....
}

P.S: 另外稍微提一下,@property UIImageView *rocket; 应更改为 @property (nonatomic) UIImageView *rocket; >。这主要是出于性能原因,因为我不希望您的火箭被多个线程访问(它不应该,这是 UI!)。

关于iphone - 当对象已经处于动画状态时,如何更改其动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13213550/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com