How could I replace UIMenuController with my own view when text is selected?
当文本被选择时,默认情况下,与UIMenuController剪切/复制弹出/粘贴等
我想用我自己的自定义视图替换它(外观相似,但高度要翻倍,以便我可以有两行按钮/自定义视图)。我该怎么办?
我知道没有简单的方法。我期望,如果有一个简单的解决方案,那将不是一个很好的选择。该代码也不能使用任何私有API。
我真的非常希望不必实现自己的文本视图,重新实现文本选择和输入以及重新实现放大视图,以便我可以编写自己的UIMenuController克隆(如果可以避免这种情况的话)。我可以替换UIMenuController对应用程序的界面非常重要,因此,如果没有其他答案,那么我可能最终会这样做。如果有人可以为我节省大量时间并提出另一种更简单的方法,我将非常感激!
开始之前,您必须了解三件事:
1)您必须编写您的自定义菜单控制器视图,但是我想您有点期望。我只知道自定义菜单控制器的商业实现,但这并不难。
2)
当决定要在自定义菜单控制器中显示哪些项目时,这将非常有用。例如,仅当用户的粘贴板包含要粘贴的字符串时,才会显示"粘贴"菜单项。
3)您可以通过收听
现在您已经了解了所有这些,这就是我要开始解决的方式:
1)文本视图为第一响应者时收听
1 2 3 4 5 6 7 | - (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)显示您的自定义菜单控制器,而不是默认的
1 2 3 4 5 6 7 8 9 10 11 12 | - (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)您可以使用全屏
1 2 3 4 5 6 | UIWindow *presentingWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; presentingWindow.windowLevel = UIWindowLevelStatusBar + 1; presentingWindow.backgroundColor = [UIColor clearColor]; [presentingWindow addSubview:controller]; [presentingWindow makeKeyAndVisible]; |
其他。 2)要确定要显示的菜单项,可以使用提到的
1 2 | BOOL canPaste = [textView canPerformAction:@selector(paste:) withSender:nil]; BOOL canSelectAll = [textView canPerformAction:@selector(selectAll:) withSender:nil]; |
其他。 3)您必须自己使用显示窗口上的
这并非易事,但这是可行的,我希望对您来说很好。祝你好运!
更新:
今天在cocoacontrols.com上弹出了一个新的菜单实现,您可能想看看:https://github.com/questbeat/QBPopupMenu
更新2:
如此答案中所述,您可以使用
获取文本视图的选定文本的框架。
我认为这可能对您有所帮助https://github.com/cxa/UIMenuItem-CXAImageSupport
UIMenuItem使用UILabel来显示其标题,这意味着我们可以使用-drawTextInRect:来支持图像。
UIMenuItem CXAImageSupport是一个肮脏的技巧,但在大多数情况下应该是安全的。不包含任何私有API。
使类别成为UIMenuItem的子类,而不是为其子类化,将获得更大的灵活性。是的,该类别也可以应用于超棒的PSMenuItem!