基于系统的UIMenuController的使用及自定义UIMenuItem

1、前言

  • 在开发中 UIMenuController 用得较少,偶尔遇到了,一时竟想不起来,因此做个回顾

2、系统默认支持 UIMenuController 的UI控件

  • UITextField

  • UITextView

  • UIWebView

  • ...

3、让 UILabel 拥有系统的 UIMenuController

  • 自定义 UILabel 内部


// 1、让自定义的 UILabel 有资格成为第一响应者
- (BOOL)canBecomeFirstResponder {
    return YES;
}
// 2、自定义的 UILabel 的 Menu 能执行哪些操作
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    // cut:剪切 / copy:复制 / paste:粘贴
    if (action == @selector(cut:) || action == @selector(copy:) || action == @selector(paste:)) {
        return  YES;
    }
    return NO;
}
// 3、那这些方法怎么实现呢
- (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;
}
// 4、系统的 menuController 方法还有 selector: / selectAll: /delete: 等
  • 外部控制器里, 给 label 添加点击手势,在手势方法里


- (void)labelClick {
    // 让 自定义的label 成为第一响应者
    [self.label becomeFirstResponder];
    // 创建 UIMenuController
    UIMenuController *menu = [UIMenuController sharedMenuController];
    // 设置 UIMenuController 的显示区域,targetRect 为指向的矩形框,inView 为以该 view 的左上角为原点
    [menu setTargetRect:self.view.bounds inView:self.view];
    // 设置可见
    [menu setMenuVisible:YES animated:YES];
}

4、让 UILabel 拥有自定义的 UIMenuController

  • 自定义 UILabel 内部

// 1、让自定义的 UILabel 有资格成为第一响应者
- (BOOL)canBecomeFirstResponder {
    return YES;
}
// 2、自定义的 UILabel 的 Menu 能执行哪些操作 , 自定义返回 NO
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    return NO;
}
  • 外部控制器里, 给 label 添加点击手势,在手势方法里

    • 自定义的 UIMenuItem 及 UIMenuItem 对应的方法写在外部(控制器)里


- (void)labelClick {
    UIMenuController *menu = [UIMenuController sharedMenuController];
    // 先处理之前的
    if (menu.menuVisible) {
        [menu setMenuVisible:NO animated:YES];
    } else {
        [self.label becomeFirstResponder];
        // 创建自定义的 UIMenuItem
        UIMenuItem *item1 = [[UIMenuItem alloc]initWithTitle:@"zhang1" action:@selector(item1Click)];
        UIMenuItem *item2 = [[UIMenuItem alloc]initWithTitle:@"zhang2" action:@selector(item2Click)];
        // 设置 MenuItem
        [menu setMenuItems:@[item1, item2]];
        [menu setTargetRect:self.view.bounds inView:self.view];
        [menu setMenuVisible:YES animated:YES];
    }
}
// 实现 UIMenuItem 对应的方法
- (void)item1Click {
}
- (void)item2Click {
}
  • 自定义了 UIMenuItem 后,若其他地方用 UIMenuController,不用这些item ,需要把 menuItems = nil 或 @[ ]

5、让 UITableCell 点击拥有自定义的 UIMenuController

  • 自定义 cell 内部


// 1、让自定义的 cell 有资格成为第一响应者
- (BOOL)canBecomeFirstResponder {
    return YES;
}
// 2、自定义的 cell 的 Menu 能执行哪些操作, 自定义返回 NO
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    return NO;
}
  • 在外部(控制器里),在 cell 点击方法里


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UIMenuController *menu = [UIMenuController sharedMenuController];
    // 先处理之前的
    if (menu.menuVisible) {
        [menu setMenuVisible:NO animated:YES];
    } else {
        DIYCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        [cell becomeFirstResponder];
        UIMenuItem *item1 = [[UIMenuItem alloc]initWithTitle:@"zhang1" action:@selector(item1Click)];
        UIMenuItem *item2 = [[UIMenuItem alloc]initWithTitle:@"zhang2" action:@selector(item2Click)];
        [menu setMenuItems:@[item1, item2]];
        // 设置 menu 的指向的矩形框
        CGRect rect = CGRectMake(0, cell.diy_height * 0.5, cell.diy_width, cell.diy_height * 0.5);
        [menu setTargetRect:rect inView:cell];
        [menu setMenuVisible:YES animated:YES];
    }
}
posted @ 2016-08-27 20:46  HOWIE-CH  阅读(3430)  评论(0编辑  收藏  举报