UIMenuController
使用系统默认的menuItem
在tableView里可以很方便的实现menuItem的显示,在UITableViewDelegate里实现三个方法即可,里面的文字不可更改
//长按是否显示Menu菜单
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
/*!
* 是否显示该item
* @brief action有 delete: copy: select: selectAll: paste: delete: ....
*/
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
NSLog(@"~~~~~~~~~~~~~%@~~~~~~~~~~~~~%@", NSStringFromSelector(action), sender);
if (action == @selector(copy:)) {
return YES;
}
return NO;
}
//对每个item的动作所做的动作
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
if (action == @selector(copy:)) {
// [UIPasteboard generalPasteboard].string = [data objectAtIndex:indexPath.row];
}
}
使用自定义的menuItem
使用自定义的menuItem需要注意一下几点:
- Menu所处的View必须实现 – (BOOL)canBecomeFirstResponder, 且返回YES
- Menu所处的View必须实现 – (BOOL)canPerformAction:withSender, 并根据显示的 item 返回YES或NO
- 使Menu所处的View成为 First Responder (becomeFirstResponder)
- 定位Menu (- setTargetRect:inView:)
- 展示Menu (- setMenuVisible:animated:)
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell becomeFirstResponder];
//坐标转换
CGRect cellRect = [tableView rectForRowAtIndexPath:indexPath];
CGRect rect = [tableView convertRect:cellRect toView:self.view];
[self.menuController setTargetRect:rect inView:self.view];
if ((rect.origin.y + rect.size.height / 2) > (CGRectGetHeight(self.view.frame) / 2)){
self.menuController.arrowDirection = UIMenuControllerArrowDown;
}
else {
self.menuController.arrowDirection = UIMenuControllerArrowUp;
}
[self.menuController setMenuVisible:YES animated:YES];
}
-(BOOL)canBecomeFirstResponder
{
return YES;
}
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(replyItemClick) || action == @selector(praiseItemClick) || action == @selector(copyItemClick) || action == @selector(reportItemClick)) {
return YES;
}
return NO;
}
-(UIMenuController *)menuController
{
if (_menuController == nil){
UIMenuItem *replyItem = [[UIMenuItem alloc] initWithTitle:@"回复" action:@selector(replyItemClick)];
UIMenuItem *praiseItem = [[UIMenuItem alloc] initWithTitle:@"点赞" action:@selector(praiseItemClick)];
UIMenuItem *copyItem = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyItemClick)];
UIMenuItem *reportItem = [[UIMenuItem alloc] initWithTitle:@"举报" action:@selector(reportItemClick)];
_menuController = [UIMenuController sharedMenuController];
[_menuController setMenuItems:[NSArray arrayWithObjects:copyItem,replyItem, praiseItem, reportItem, nil]];
}
return _menuController;
}
- becomeFirstResponder方法,使得View和ViewController的self成为第一响应者,可以在相应文件的任意地方调用实现该方法,不过建议与UIMenuController放在一起。
- 设置-(BOOL) canBecomeFirstResponder的返回值为YES,原因不言而喻。
- 重载函数-(BOOL) canPerfomAction:(SEL)action withSender:(id)sender,设置要显示的菜单项,返回值为YES。若不进行任何限制,则将显示系统自带的所有菜单项(很多的,自己可以试一下),在此,只显示自定义的4项。如果将系统默认的菜单也显示出来,那么自定义的菜单将作为第二菜单,调用菜单时默认显示的是第一菜单,然后第二菜单显示在最后面
注意:- setTargetRect:inView: 方法显示的rect和view,如果在tableView中,不能直接将cell的rect作为此处的rect,而应该将其转换为在屏幕上的rect