在开始之前,您必须了解三件重要的事情:
1)您必须编写自定义菜单控制器视图,但我猜您有点期待。我只知道自定义菜单控制器的商业实现,但这应该不会太难。
2)UIResponder
被调用有一个有用的方法-canPerformAction:withSender:
。在UIResponder 类参考中阅读更多关于它的信息。您可以使用该方法来确定您的文本视图是否支持特定的标准操作(在UIResponderStandardEditActions协议中定义)。
这在决定在自定义菜单控制器中显示哪些项目时很有用。例如,仅当用户的粘贴板包含要粘贴的字符串时,才会显示粘贴菜单项。
3)UIMenuController
您可以通过收听UIMenuControllerWillShowMenuNotification
通知来检测何时显示。
现在你知道了所有这些,这就是我开始解决这个问题的方法:
1)UIMenuControllerWillShowMenuNotification
当文本视图是第一响应者时监听s
- (void)textViewDidBeginEditing:(UITextView *)textView {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuWillBeShown:) name:UIMenuControllerWillShowMenuNotification object:nil];
}
- (void)textViewDidEndEditing:(UITextView *)textView {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerWillShowMenuNotification object:nil];
}
2)显示您的自定义菜单控制器而不是默认的UIMenuController
- (void)menuWillBeShown:(NSNotification *)notification {
CGRect menuFrame = [[UIMenuController sharedMenuController] menuFrame];
[[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO]; // Don't show the default menu controller
CustomMenuController *controller = ...;
controller.menuItems = ...;
// additional stuff goes here
[controller setTargetRectWithMenuFrame:menuFrame]; // menuFrame is in screen coordinates, so you might have to convert it to your menu's presenting view/window/whatever
[controller setMenuVisible:YES animated:YES];
}
杂项。1)您可以使用全屏UIWindow
显示自定义菜单,以便它可以与状态栏重叠。
UIWindow *presentingWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
presentingWindow.windowLevel = UIWindowLevelStatusBar + 1;
presentingWindow.backgroundColor = [UIColor clearColor];
[presentingWindow addSubview:controller];
[presentingWindow makeKeyAndVisible];
杂项。2)为了确定要显示的菜单项,您可以使用提到的-canPerformAction:withSender:
BOOL canPaste = [textView canPerformAction:@selector(paste:) withSender:nil];
BOOL canSelectAll = [textView canPerformAction:@selector(selectAll:) withSender:nil];
杂项。3)您必须通过UITapGestureRecognizer
在呈现窗口上使用 a 或类似的东西自己处理关闭菜单。
这并不容易,但它是可行的,我希望它对你很有效。祝你好运!
更新:
今天 cocoacontrols.com 上弹出了一个新的菜单实现,您可能想查看:https ://github.com/questbeat/QBPopupMenu
更新 2:
如本答案中所述,您可以使用-caretRectForPosition:
.