1

我想要的是让我的 iPhone 应用程序一直知道摇动手势,除非有任何UITextfieldUITextview成为 firstResponder。

(我跟着这个:https ://stackoverflow.com/questions/150446/how-do-i-detect-when-someone-shakes-an-iphone/1351486#1351486I )

我子类化UIWindow并实现motionEnded:withEvent:了方法,即使我将 a 设置UITextView为 firstResponder,它也可以工作。我的自定义UIWindow调用motionEnded:withEvent:,即使它不是 firstResponder。

所以问题是我UItextView的默认撤消管理器不再响应抖动。无论 view-hierarchy 或 firstResponders 如何更改,UIWindow都接管了 Shake-Gesture 的所有处理。

任何人都可以阐明如何暂时禁用 UIWindow 的检测或让当前的 firstResponder 根据我的实现接管 Shaking-Gesture 吗?

提前致谢!

4

1 回答 1

1

无论如何,我找到了解决方案。

默认的撤消管理器实际上仍然在那里秘密地保存对 UITextView 所做的所有操作。

由于UIWindow接管了运动处理,首先我尝试通过覆盖motionEnded:withEvent:包含我的UITextView.

其次,获取 undoManager ,[myTextView undoManager]然后您可以向它发送undoredo消息。

现在模仿默认的撤消管理器警报视图,使用redoMenuItemTitleandundoMenuItemTitle获取按钮标题,然后使用canUndoandcanRedo决定是否显示按钮。

编辑:这是我的应用程序中的代码:

- (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];
    }
}
于 2010-08-13T13:09:23.597 回答