最近在做私信功能,有山寨微信的味道,需要支持发图片,语音,文字.
支持删除复制转发,用UIMenuController实现.
功能均完成后,发现UIMenuController有时候不显示.
网上此问题统一的解答是:
显示弹出菜单,必须实现3个方法,缺一不可:
1.becomFirstResponder方法,使view或者viewController的self成为第一响应者,可以在相应文件的任意地方调用实现该方法,不过建议与UIMenuController放在一起。
[self becomeFirstResponder];
-(BOOL) canBecomeFirstResponder{ returnYES; }
-(BOOL) canPerformAction:(SEL)action withSender:(id)sender{ if (action ==@selector(menuItem1Pressed:) || action ==@selector(menuItem2Pressed:)|| action == @selector(menuItem3Pressed:) || action ==@selector(menuItem4Pressed:)){ returnYES; } returnNO;//隐藏系统默认的菜单项 }
但是,我的UIMenuController有时候可以显示,有时候不能显示,为什么呢?
测试发现,只要发送图片后就不能弹出UIMenuController.
后来发现原来是发图前,自写了一个view预览图片,此view的superview是一个window:
window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; window.windowLevel = UIWindowLevelAlert; window.backgroundColor = [UIColor clearColor]; [window makeKeyAndVisible];
原来如此...UIMenuController的KeyWindow已经被上面覆盖,so,FirstResponder也不是UIMenuController父窗口的父窗口的...上了
后来在长按消息内加:
UIWindow *window = [[UIApplication sharedApplication].delegate window]; if ([window isKeyWindow] == NO) { [window becomeKeyWindow]; [window makeKeyAndVisible]; }
完成~
发图后也能显示UIMenuController了~
上面的方法,[self becomeFirstResponder];时,在ios5/6没问题,ios7却crash:didChangeToFirstResponder
stackoverflow.com上也有几个此问题,但根本和我的原因不同.
经过几次查找推测,最终解决:
1,首先,在uitableview层
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (IOS7) { if (scrollView == myTable) { NSArray *_cellArray = [myTable visibleCells]; if([_cellArray count] > 0) { [_cellArray makeObjectsPerformSelector:@selector(hiddenMenu)]; } } } }
2,在uitableviewcell内加hiddenMenu
-(void)hiddenMenu { if (IOS7) { if ([self canBecomeFirstResponder]) { if ([self isFirstResponder]) { [self resignFirstResponder]; } } UIMenuController *menu = [UIMenuController sharedMenuController]; if ([menu isMenuVisible]) { [menu setMenuVisible:NO animated:YES]; } } }
3,并在UILongPressGestureRecognizer添加的地方加delegate
_recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; if (IOS7) { _recognizer.delegate = self; } [recognizerView addGestureRecognizer:_recognizer]; [_recognizer release];