2010-08-13 4 views
1

UITextfield 또는 UITextview이 firstResponder가 될 때를 제외하고 항상 iPhone 앱이 흔들리는 동작을 인식하도록하고 싶습니다. I는 서브 클래스 UIWindowUIWindow 하위 클래스의 흔들기 감지 기능이 기본 텍스트 실행 취소 관리자를 대신합니다

motionEnded:withEvent: 및 방법을 구현하고 난 firstResponder UITextView가되도록 설정 한 경우에도 작동 :

은 (I https://stackoverflow.com/questions/150446/how-do-i-detect-when-someone-shakes-an-iphone/1351486#1351486I이 따랐다). 내 맞춤 UIWindow은 firstResponder가 아니더라도 motionEnded:withEvent:으로 전화합니다.

UItextView의 기본 실행 취소 관리자가 더 이상 떨리는 것에 응답하지 않습니다. UIWindow은 뷰 계층 구조 또는 firstResponders가 어떻게 변경되었는지에 관계없이 Shake-Gesture의 모든 처리를 담당합니다.

일시적으로 UIWindow의 감지를 비활성화하는 방법에 대한 정보를 얻거나 현재 firstResponder가 구현에 기반한 떨리는 제스처를 대신 처리 할 수 ​​있습니까? 사전에

감사합니다!

답변

1

어쨌든 해결책을 찾았습니다.

기본적으로 실행 취소 관리자는 실제로 UITextView에 수행 한 모든 작업을 비밀리에 저장합니다.

UIWindow은 모션 처리를 담당하므로 먼저 UITextView이 포함 된 viewController에서 motionEnded:withEvent:을 재정 의하여 다시 가져 오려고합니다.

두 번째로 [myTextView undoManager]에 의해 undoManager를 가져온 다음 undo 또는 redo 메시지를 보낼 수 있습니다.

이제 기본 실행 취소 관리자 alertview을 모방하는 버튼을 표시할지 여부를 결정하는 canUndocanRedo을 사용 후, 버튼 타이틀을 얻기 위해 redoMenuItemTitleundoMenuItemTitle를 사용합니다.

편집는 :

- (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]; 
    } 
} 
: 여기에 내 응용 프로그램의 코드입니다