2010-08-13 2 views
1

Ce que je veux, c'est que mon application iPhone soit toujours consciente du mouvement de secousse, sauf si UITextfield ou UITextview devient firstResponder.La détection de mouvement Shake dans la sous-classe UIWindow prend en charge le gestionnaire d'annulation de texte par défaut

(j'ai suivi ceci: https://stackoverflow.com/questions/150446/how-do-i-detect-when-someone-shakes-an-iphone/1351486#1351486I)

I sous-classe UIWindow et mis en œuvre la méthode motionEnded:withEvent: et il fonctionne même si je mets un UITextView être firstResponder. Mon UIWindow personnalisé appelle motionEnded:withEvent: même si ce n'est pas firstResponder.

Le problème est que le gestionnaire d'annulation par défaut de UItextView ne répond plus aux vibrations. Le UIWindow prend en charge toute la gestion de Shake-Gesture, quelle que soit la façon dont la hiérarchie de vue ou les firstResponders ont été modifiés. Quelqu'un pourrait-il nous éclairer sur la façon de désactiver temporairement la détection d'UIWindow ou de faire en sorte que le premier répondeur actuel prenne en charge le mouvement d'agitation en fonction de l'implémentation que j'ai?

Merci d'avance!

Répondre

1

De toute façon j'ai trouvé une solution.

Le gestionnaire d'annulation par défaut est toujours là en train d'enregistrer secrètement toutes les actions effectuées sur UITextView.

Depuis UIWindow prend en charge la gestion des mouvements, d'abord je tente de le reprendre en remplaçant motionEnded:withEvent: dans le viewController qui contient mon UITextView.

Ensuite, obtenez le undoManager par [myTextView undoManager] puis vous pouvez lui envoyer des messages undo ou redo.

maintenant pour mimer le gestionnaire undo par défaut alertview, utilisez redoMenuItemTitle et undoMenuItemTitle pour obtenir le titre de bouton, puis utilisez canUndo et canRedo de décider si vous souhaitez afficher le bouton ou non.

Modifier: Voici le code de mon application:

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { 
    if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) { 

     //textUndoManager is an ivar but it was just a reference to the undoManager 
     //textUndoManager = [myTextView undoManager]; <--- in viewDidLoad: 
     NSString *undoButtonTitle = nil; 
     NSString *redodoButtonTitle = nil; 
     NSString *alertViewTitle = nil; 
     if ([textUndoManager canUndo]) 
      undoButtonTitle = [NSString stringWithString:[textUndoManager undoMenuItemTitle]]; 
     if ([textUndoManager canRedo]) 
      redodoButtonTitle = [NSString stringWithString:[textUndoManager redoMenuItemTitle]]; 
     if (!undoButtonTitle && !redodoButtonTitle) 
      alertViewTitle = @"Nothing to Undo"; 

     UIAlertView *alertView; 
     if (undoButtonTitle == nil) { 
      alertView = [[UIAlertView alloc] initWithTitle:alertViewTitle message:nil delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:redodoButtonTitle, nil]; 
     } else { 
      alertView = [[UIAlertView alloc] initWithTitle:alertViewTitle message:nil delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:undoButtonTitle, redodoButtonTitle, nil]; 
     } 

     [alertView show]; 
    } 
} 

//UIAlertViewDelegate 
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 
    if ([[alertView buttonTitleAtIndex:buttonIndex] isEqualToString:[textUndoManager undoMenuItemTitle]]) { 
     [textUndoManager undo]; 
    } 
    if ([[alertView buttonTitleAtIndex:buttonIndex] isEqualToString:[textUndoManager redoMenuItemTitle]]) { 
     [textUndoManager redo]; 
    } 
} 
Questions connexes