2009-09-23 9 views
0

Ok. Je sais que le titre peut prêter à confusion.pour l'exécution de la boucle ne permet pas de touches sur l'iPhone

Logique J'ai implémenté quelque chose comme ça.

  • Il y a un détecteur en application (comme indicateur de vitesse à vélo - flèche mobile)
  • Lorsque les robinets utilisateur bouton Lancer la recherche - première méthode est exécutée.
  • NowStartMovements décide des rotations aléatoires & nombre aléatoire à arrêter
  • Il y a 1 à 10 nombres sur le détecteur.
  • Tout fonctionne bien jusqu'à maintenant.
  • Le code suivant est sans erreur.
  • flèche se déplace parfaitement & arrête à la position correcte (décidé au hasard)

  • Mais le problème est «J'ai mis en boucle pour les mouvements »

  • Ainsi, lors de l'exécution de la boucle, l'interaction de l'utilisateur ISN n'est pas activé.

J'ai également ajouté le code que j'ai implémenté.


-(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]); 
} 
} 

Répondre

2

Vous aurez besoin de réécrire votre logique il est donc la minuterie qui fait le sommeil, pas usleep. Réécrivez votre fonction de sorte que chaque itération de la minuterie répétable fasse ce qui est dans la boucle for.

Le problème est que la boucle for est en veille sur le thread principal. Si vous utilisez une minuterie et que vous réglez les répétitions sur YES, cela fait essen tiquement le pattern for/sleep que vous faites. Lorsque vous voulez l'arrêter, appelez [timer invalidate];

+0

J'ai mis en œuvre selon vos suggestions. –

1

Idéalement, vous utiliseriez une minuterie pour programmer les mouvements de l'aiguille. La solution la plus rapide à votre code existant est la suivante:

  • En StartScan, changer -scheduledTimerWithTimeInterval:--performSelectorInBackground:

  • En nowStartMovements, changer -detachNewThreadSelector: à -performSelectorOnMainThread:

De cette façon, le usleep arrive sur un thread d'arrière-plan et ne bloque pas le thread principal. L'interface utilisateur sera gelée tant que le thread principal est bloqué.

+0

correct. exact. –