我想要的是让我的iPhone应用程序始终知道摇动手势,除非任何UITextfield
或UITextview
成为firstResponder。
我将UIWindow
子类化并实现了motionEnded:withEvent:
方法,即使我将UITextView
设置为firstResponder也能正常工作。我的自定义UIWindow
会调用motionEnded:withEvent:
,即使它不是第一个响应者。
问题是我UItextView
的默认撤消管理器不再响应。无论视图层次结构或firstResponder如何更改,UIWindow
都会接管Shake-Gesture的所有处理。
有没有人能够了解如何暂时禁用UIWindow的检测或让当前的firstResponder根据我的实现接管Shaking-Gesture?
提前致谢!
答案 0 :(得分:1)
无论如何我找到了解决方案。
默认的撤消管理器实际上仍然保存了对UITextView进行的所有操作。
由于UIWindow
接管了动作处理,首先我尝试通过覆盖包含motionEnded:withEvent:
的viewController中的UITextView
来取回它。
其次,通过[myTextView undoManager]
获取undoManager,然后您可以向其发送undo
或redo
条消息。
现在模仿默认的撤消管理员提醒视图,使用redoMenuItemTitle
和undoMenuItemTitle
获取按钮标题,然后使用canUndo
和canRedo
来决定是否显示按钮
修改:以下是我的应用程序中的代码:
- (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];
}
}