开发时有时会遇到,textView为第一响应时,menu菜单要显示,若不移除textView响应,会导致menu菜单显示textView的系统菜单,粘贴、选择等。
如下图
如果移除响应,体验会很不好,尤其是即时通讯App。
尝试了多种方法后,找到一种简单的方法,且可以menu、键盘二者共存。
就是继承一个系统TextView,h文件添加一个属性isShowMenu,m文件中重写canPerformAction方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
//拦截menu菜单
if(self.isShowMenu)
{
return NO;
}
else
{
return [supercanPerformAction:action withSender:sender];
}
}
之后,在初始化menu的地方加上第一响应判断
if([self.myTextView isFirstResponder])
{
self.myTextView.isShowMenu = YES;
}
else
{
[self becomeFirstResponder];
}
NSMutableArray *menuItems = [[NSMutableArray alloc] init];
UIMenuItem *itCopy = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(handleCopyItem)];
[menuItems addObject:itCopy];
UIMenuItem *deleteItem = [[UIMenuItem alloc] initWithTitle:@"删除" action:@selector(handleDeleteItem)];
[menuItems addObject:deleteItem];
UIMenuItem *replyItem = [[UIMenuItem alloc] initWithTitle:@"收藏" action:@selector(handleColectItem)];
[menuItems addObject:replyItem];
[UIMenuController sharedMenuController].menuItems = menuItems;
[[UIMenuController sharedMenuController] setTargetRect:CGRectMake(0, 0, view.frame.size.width, view.frame.size.height) inView:view];
[[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
最后一步,在控制器里面添加menu消失的通知,在通知里面重置isShowMenu
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuControllerWillHide:) name:UIMenuControllerWillHideMenuNotification object:nil];
- (void)menuControllerWillHide: (NSNotification*)notification
{
//还原menu
[[UIMenuController sharedMenuController] setMenuItems:@[]];
self.myTextView.isShowMenu = NO;
}
就大功告成了!是不是很easy,又可以愉快的玩耍了
修改完成后结果
附demo地址:
GitHub - j12y12x12/menuControllerAndTextView: 1.menu菜单显示时不隐藏键盘;2.textView为第一响应者时,menu菜单显示粘贴,选择等textView自带菜单