2009-09-23 44 views
0

好的。我知道标题可能会令人困惑。for循环执行不允许触摸iPhone

逻辑我已经实现了这样的东西。

  • 有一个在应用程序中的检测器(如自行车速度表 - 移动箭头)
  • 当用户开始抽头扫描按钮 - 第一方法执行。
  • NowStartMovements决定随机旋转&随机数停止
  • 检测器上有1到10个数字。
  • 到目前为止,每件事情都很好。
  • 以下代码无错误。
  • 箭在适当位置(随机决定)

  • 移动完美&停止,但问题是“我已经实现了循环的运动”

  • 因此,当for循环执行,用户交互ISN没有启用。

我还添加了我已经实现的代码。


-(IBAction)ScanStart:(id)sender 
{ 
btnScan.enabled=NO; stopThroughButtons=NO; shouldNeedleGoRightSide=YES; currentNeedleValue=1; nxtNeedleValue=2; 
[NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(nowStartMovements) userInfo:nil repeats:NO]; 
} 

-(void)nowStartMovements{ 
totalRotations=arc4random()%9; if(totalRotations<3) totalRotations+=3; 
currentRotation=0;stopValue=arc4random()%11; if(stopValue<1)stopValue=1; 
int totalMovements=(totalRotations-1)*10 + ((totalRotations%2==0)?10-stopValue:stopValue), i; 
for(i=0;i<totalMovements;i++){ 
    if (stopThroughButtons) return; 
    [NSThread detachNewThreadSelector:@selector(moveNeedle) toTarget:self withObject:nil]; 
    usleep(200000); 
} 
} 

-(void)moveNeedle{ 
spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
double fromValue=[[arrayOfFloatValues objectAtIndex:currentNeedleValue-1] doubleValue]; 
double toValue=[[arrayOfFloatValues objectAtIndex:nxtNeedleValue-1] doubleValue]; 
spinAnimation.duration=0.2; 
spinAnimation.fromValue=[NSNumber numberWithFloat:fromValue]; 
spinAnimation.toValue = [NSNumber numberWithFloat:toValue]; 
[imgNideel.layer addAnimation:spinAnimation forKey:@"spinAnimation"]; 
[NSThread detachNewThreadSelector:@selector(MoveActualNeedle) toTarget:self withObject:nil]; 
} 

-(void)MoveActualNeedle{ 
if(shouldNeedleGoRightSide){   
    if(currentNeedleValue<9) { currentNeedleValue++; nxtNeedleValue++;} 
    else { shouldNeedleGoRightSide=NO; currentNeedleValue=10; nxtNeedleValue=9; 
} 
    imgNideel.transform=CGAffineTransformMakeRotation([[arrayOfFloatValues objectAtIndex:currentNeedleValue-1] doubleValue]); 
} else { 
    if(currentNeedleValue>2){ currentNeedleValue--; nxtNeedleValue--;} 
    else { shouldNeedleGoRightSide=YES; currentNeedleValue=1; nxtNeedleValue=2; 
} 
    imgNideel.transform=CGAffineTransformMakeRotation([[arrayOfFloatValues objectAtIndex:currentNeedleValue-1] doubleValue]); 
} 
} 

回答

2

你需要重写你的逻辑,所以它是做睡眠,而不是usleep定时器。重写你的函数,以便可重复计时器的每次迭代都执行for循环中的操作。

问题是for循环正在主线程中睡眠。如果您使用计时器并将重复设置为YES,那么这基本上会执行您正在执行的for/sleep模式。当你想停止它调用[定时器无效];

+0

我已根据您的建议实施。 – 2009-09-23 23:09:15

1

理想情况下,您需要使用计时器来安排针的移动。最快的解决办法,以现有的代码是这样的:

  • StartScan,改变-scheduledTimerWithTimeInterval:-performSelectorInBackground:

  • nowStartMovements,改变-detachNewThreadSelector:-performSelectorOnMainThread:

这样,usleep发生在一个后台线程并且不会阻塞主线程。只要主线程被阻塞,UI将被冻结。

+0

正确。精确。 – 2009-09-23 23:08:42