图中黑色的菜单就是UIMenuController
默认已经支持UIMenuController的控件:
- UITextField
- UITextView
- UIWebView
让其他控件也支持UIMenuController(比如UILabel)
- 自定义UILabel,让其成为第一响应者,并添加点击手势
- (void)setUp {
// 1.设置label可以交互
self.userInteractionEnabled = YES;
// 2.添加点击手势
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(click)]];
}
- (void)click {
// 3.设置label为第一响应者,只有成为响应者才能够将MenuController显示在其上面
[self becomeFirstResponder];
// 4.初始化UIMenuController
UIMenuController *menuController = [UIMenuController sharedMenuController];
// 5.设置UIMenuController显示的位置
// targetRect : 将要显示所在label的frame;
// view : targetRect所在的坐标系参照物(父view或self)
[menuController setTargetRect:self.frame inView:self.superview];
// [menuController setTargetRect:self.bounds inView:self];作用同上
// 6.显示UIMenuController
[menuController setMenuVisible:YES animated:YES];
}
/** * 让label有资格成为第一响应者 */
- (BOOL)canBecomeFirstResponder{
return YES;
}
/** * label能执行哪些操作(比如copy, paste等等)
* @return YES:支持这种操作
*/
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{
if (action == @selector(cut:) || action == @selector(copy:) || action == @selector(paste:)) return YES; return NO;
}
- (void)cut:(UIMenuController *)menu {
// 将自己的文字复制到粘贴板
[self copy:menu];
// 清空文字
self.text = nil;
}
- (void)copy:(UIMenuController *)menu{
// 将自己的文字复制到粘贴板
UIPasteboard *board = [UIPasteboard generalPasteboard];
board.string = self.text;
}
- (void)paste:(UIMenuController *)menu{
// 将粘贴板的文字 复制 到自己身上
UIPasteboard *board = [UIPasteboard generalPasteboard];
self.text = board.string;
}
自定义UIMenuController内部的Item(以cell为例)
- 点击cell显示/隐藏MenuController
- 由于手动添加的MenuItem默认触发控制器中的方法,所以将MenuController的显示/隐藏,添加MenuItem写到控制器中(上面Label的例子是让控件支持系统自带的一些MenuItem,现在讲的是如何支持自己定义的一些MenuItem)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// 点击cell弹出UIMenuController
// 1.如果menuController已经在显示,就隐藏他
// 注意,如果有一个cell正在显示menuController,这时再点击另外一个cell,上一个cell的menuController会消失,当前点击cell会显示,这是因为上一个cell不再是第一响应者了,menuController会自动释放
UIMenuController *menuController = [UIMenuController sharedMenuController];
if (menuController.isMenuVisible) {
[menuController setMenuVisible:NO animated:YES];
}else {
// 2.显示MenuController
// 先设置cell为第一响应者,同时不要忘记在cell中重写canBecomeFirstResponder和canPerformAction:withSender:
JCMTopicCommentCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell becomeFirstResponder];
// 添加menuItem
UIMenuItem *item01 = [[UIMenuItem alloc]initWithTitle:@"顶" action:@selector(ding:)];
UIMenuItem *item02 = [[UIMenuItem alloc]initWithTitle:@"回复" action:@selector(response:)];
UIMenuItem *item03 = [[UIMenuItem alloc]initWithTitle:@"举报" action:@selector(report:)];
menuController.menuItems = @[item01,item02,item03];
// 设置menuControoler显示位置
CGRect showRect = CGRectMake(cell.x, cell.y + cell.height/2, cell.width, cell.height);
[menuController setTargetRect:showRect inView:cell.superview];
// 显示menuController [menuController setMenuVisible:YES animated:YES];
}
}
#pragma mark - MenuController处理
// MenuController手动添加的item的方法实现必须放在controller中
- (void)ding:(UIMenuController *)menu {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSLog(@"%s %@", __func__, [self commentInIndexPath:indexPath].content);
}
- (void)response:(UIMenuController *)menu {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSLog(@"%s %@", __func__, [self commentInIndexPath:indexPath].content);
}
- (void)report:(UIMenuController *)menu {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSLog(@"%s %@", __func__, [self commentInIndexPath:indexPath].content);
}
// 是否可以成为第一响应者
- (BOOL)canBecomeFirstResponder {
return YES;
}
// 是否可以执行哪些方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
return NO;
}```