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

一、前言

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

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

  • UITextFieldui

  • UITextViewcode

  • UIWebVieworm

  • ...开发

三、让 UILabel 拥有系统的 UIMenuController

  • 自定义 UILabel 内部
// 一、让自定义的 UILabel 有资格成为第一响应者
- (BOOL)canBecomeFirstResponder {
    return YES;
}
// 二、自定义的 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;
}
// 三、那这些方法怎么实现呢
- (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;
}
// 四、系统的 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];
}

四、让 UILabel 拥有自定义的 UIMenuController

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

    • 自定义的 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 或 @[ ]

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

  • 自定义 cell 内部
// 一、让自定义的 cell 有资格成为第一响应者
- (BOOL)canBecomeFirstResponder {
    return YES;
}
// 二、自定义的 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];
    }
}
相关文章
相关标签/搜索