如何防止UIAnimation干扰CADisplayLink
How to prevent UIAnimation from interfering with CADisplayLink
在我目前的项目中有两个主要机制。一系列不断在屏幕上移动的对象,以及您按下多个按钮来移动 2 个对象的机制。对于在屏幕上移动的一系列对象,我使用了 CADisplayLink,而另一个机制是使用 UIAnimation,但是当我 运行 我的项目时,我注意到 UIAnimation 干扰了每当按下按钮时,对象都会瞬间与 CADisplayLink 链接。我该如何解决这个问题??
下面是我对这两个机制的代码
-(IBAction)tap{
CGRect frame = Person.frame;
frame.origin.x = 16;
frame.origin.y = 37;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
Person.frame = frame;
[UIView commitAnimations];
}
-(IBAction)tap1{
CGRect frame = Person.frame;
frame.origin.x = 241;
frame.origin.y = 37;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
Person.frame = frame;
[UIView commitAnimations];
}
-(IBAction)tapR1{
CGRect frame = Person1.frame;
frame.origin.x = 302;
frame.origin.y = 37;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
Person1.frame = frame;
[UIView commitAnimations];
}
-(IBAction)tapR2{
CGRect frame = Person1.frame;
frame.origin.x = 526;
frame.origin.y = 37;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
Person1.frame = frame;
[UIView commitAnimations];
}
-(void)GameOver{
}
-(void)Score{
ScoreNumber = ScoreNumber + 1;
ScoreLabel.text = [NSString stringWithFormat:@"%i", ScoreNumber];
}
-(IBAction)StartGame:(id)sender{
StartGame.hidden = YES;
Spike.hidden = NO;
Spike1.hidden = NO;
Spike2.hidden = YES;
SpikeR.hidden = NO;
SpikeR1.hidden = NO;
SpikeR2.hidden = NO;
circle.hidden = NO;
ScoreLabel.hidden = NO;
[self PlaceBars];
[self PlaceBars1];
Movement = [CADisplayLink displayLinkWithTarget:self selector:@selector(BarMoving)];
[Movement addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
-(void)BarMoving{
Spike.center = CGPointMake(Spike.center.x, Spike.center.y - 5);
Spike1.center = CGPointMake(Spike1.center.x, Spike1.center.y - 5);
Spike2.center = CGPointMake(Spike1.center.x, Spike1.center.y - 5);
if (Spike2.center.y == -115) {
[self PlaceBars];
}
SpikeR.center = CGPointMake(SpikeR.center.x, SpikeR.center.y - 5);
SpikeR1.center = CGPointMake(SpikeR1.center.x, SpikeR1.center.y - 5);
SpikeR2.center = CGPointMake(SpikeR2.center.x, SpikeR2.center.y - 5);
if (SpikeR2.center.y == -115) {
[self PlaceBars1];
}
}
我认为您对所有移动机制都使用 CADisplayLink。
但是,将移动逻辑委托给您的对象,而不是让父对象管理所有移动。这是您将在 Unity 中看到的模式。
在您的情况下,当 CADisplayLink 更新时,遍历您的对象并对每个对象调用 update() 方法。此更新方法将该对象向上移动 5 个点,就像 BarMoving() 在正常状态下所做的那样。在点击状态下,它逐渐移动到[241, 37]。
当用户点击对象时,将其状态从正常状态更改为点击状态,设置初始速度、位置算法、目标点和上面提到的 update() 方法将处理点击移动。
在我目前的项目中有两个主要机制。一系列不断在屏幕上移动的对象,以及您按下多个按钮来移动 2 个对象的机制。对于在屏幕上移动的一系列对象,我使用了 CADisplayLink,而另一个机制是使用 UIAnimation,但是当我 运行 我的项目时,我注意到 UIAnimation 干扰了每当按下按钮时,对象都会瞬间与 CADisplayLink 链接。我该如何解决这个问题??
下面是我对这两个机制的代码
-(IBAction)tap{
CGRect frame = Person.frame;
frame.origin.x = 16;
frame.origin.y = 37;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
Person.frame = frame;
[UIView commitAnimations];
}
-(IBAction)tap1{
CGRect frame = Person.frame;
frame.origin.x = 241;
frame.origin.y = 37;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
Person.frame = frame;
[UIView commitAnimations];
}
-(IBAction)tapR1{
CGRect frame = Person1.frame;
frame.origin.x = 302;
frame.origin.y = 37;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
Person1.frame = frame;
[UIView commitAnimations];
}
-(IBAction)tapR2{
CGRect frame = Person1.frame;
frame.origin.x = 526;
frame.origin.y = 37;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
Person1.frame = frame;
[UIView commitAnimations];
}
-(void)GameOver{
}
-(void)Score{
ScoreNumber = ScoreNumber + 1;
ScoreLabel.text = [NSString stringWithFormat:@"%i", ScoreNumber];
}
-(IBAction)StartGame:(id)sender{
StartGame.hidden = YES;
Spike.hidden = NO;
Spike1.hidden = NO;
Spike2.hidden = YES;
SpikeR.hidden = NO;
SpikeR1.hidden = NO;
SpikeR2.hidden = NO;
circle.hidden = NO;
ScoreLabel.hidden = NO;
[self PlaceBars];
[self PlaceBars1];
Movement = [CADisplayLink displayLinkWithTarget:self selector:@selector(BarMoving)];
[Movement addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
-(void)BarMoving{
Spike.center = CGPointMake(Spike.center.x, Spike.center.y - 5);
Spike1.center = CGPointMake(Spike1.center.x, Spike1.center.y - 5);
Spike2.center = CGPointMake(Spike1.center.x, Spike1.center.y - 5);
if (Spike2.center.y == -115) {
[self PlaceBars];
}
SpikeR.center = CGPointMake(SpikeR.center.x, SpikeR.center.y - 5);
SpikeR1.center = CGPointMake(SpikeR1.center.x, SpikeR1.center.y - 5);
SpikeR2.center = CGPointMake(SpikeR2.center.x, SpikeR2.center.y - 5);
if (SpikeR2.center.y == -115) {
[self PlaceBars1];
}
}
我认为您对所有移动机制都使用 CADisplayLink。
但是,将移动逻辑委托给您的对象,而不是让父对象管理所有移动。这是您将在 Unity 中看到的模式。
在您的情况下,当 CADisplayLink 更新时,遍历您的对象并对每个对象调用 update() 方法。此更新方法将该对象向上移动 5 个点,就像 BarMoving() 在正常状态下所做的那样。在点击状态下,它逐渐移动到[241, 37]。
当用户点击对象时,将其状态从正常状态更改为点击状态,设置初始速度、位置算法、目标点和上面提到的 update() 方法将处理点击移动。