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];
}
}

基于系统的UIMenuController的使用及自定义UIMenuItem的更多相关文章

  1. R语言简单实现聚类分析计算与分析(基于系统聚类法)

    聚类分析计算与分析(基于系统聚类法) 下面以一个具体的例子来实现实证分析.2008年我国其中31个省.市和自治区的农村居民家庭平均每人全年消费性支出. 根据原始数据对我国省份进行归类统计. 原始数据如 ...

  2. 最简单的基于DirectShow的示例:视频播放器自定义版

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  3. 基于jQuery自适应宽度跟高度可自定义焦点图

    基于jQuery自适应宽度跟高度可自定义焦点图.这是一款带左右箭头,缩略小图切换的jQuery相册代码.效果图如下: 在线预览   源码下载 实现的代码. html代码: <section cl ...

  4. 【咸鱼教程】基于系统时间的计时器DateTimer(不受FPS影响)

    教程目录一 计时器简介二 计时器实现三 Demo下载 一 计时器简介在手机上跑游戏时,可能由于运动物体过多,导致帧频太低,计时不准确.比如一些倒计时的游戏,可能倒计时30s,变成了35s.比如ipho ...

  5. 基于VueJS的render渲染函数结合自定义组件打造一款非常强大的IView 的Table

    基于VueJS的render渲染函数结合自定义组件打造一款非常强大的IView 的Table https://segmentfault.com/a/1190000015970367

  6. 笨重的mfc还在基于系统控件,熟练的mfc工程师还比不过学习Qt一个月的学生开发效率高(比较精彩,韦易笑)

    作者:韦易笑链接:https://www.zhihu.com/question/29636221/answer/45102191来源:知乎著作权归作者所有,转载请联系作者获得授权. 更新:擦,本来只有 ...

  7. ubuntu 使用 vsftpd 基于系统用户配置相互隔离的 ftp (ftps) 服务

    我们在日常使用 UbuntuServer 服务器时,经常会直接使用基于 ssh 的  sftp 连接服务器直接进行文件上传和下载,不过这个方式其实有一定的安全隐患,当一个团队有多个人员,需要连接服务器 ...

  8. 基于Bootstrap里面的Button dropdown打造自定义select

    最近工作非常的忙,在对一个系统进行改版.项目后台是MVC1.0开发的,但是前端部分已经改过几个版本,而已之前的设计师很强大,又做设计又做前端开发.而已很时尚和前沿,使用了一直都很热门的Bootstra ...

  9. Android系统在新进程中启动自定义服务过程(startService)的原理分析

    在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验.Android系统为我们提供了一个Service类,我们可以实现 ...

随机推荐

  1. Codeforces Round #310 (Div. 1) A. Case of Matryoshkas 水题

    C. String Manipulation 1.0 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contes ...

  2. 一道模板元编程题源码解答(replace_type)

    今天有一同学在群上聊到一个比较好玩的题目(本人看书不多,后面才知是<C++模板元编程>第二章里面的一道习题), 我也抱着试一试的态度去完成它, 这道题也体现了c++模板元编程的基础和精髓: ...

  3. Session丢失,都是CDN惹的祸

    周六下午,正在外面吃饭,运营的同事火急火燎地给我打电话,说是网站出问题了,用户登录不了,而且这种情况也不是全部,只有部分地区有问题.没办法,只能回到家里找问题,打开代码,翻来覆去地找问题,搞了整整一下 ...

  4. C++ Qt 访问权限总结

    总结:C++的访问修饰符的作用是以类为单位,而不是以对象为单位. 通俗的讲,同类的对象间可以“互相访问”对方的数据成员,只不过访问途径不是直接访问. 步骤是:通过一个对象调用其public成员函数,此 ...

  5. poll机制分析

    更多文档:http://pan.baidu.com/s/1sjzzlDF linux poll/select用法及在字符驱动中的简单实现 1.poll和select 使用非阻塞I/O 的应用程序常常使 ...

  6. .net中的多线程

    一.多线程的概念        什么是进程呢?当一个程序开始运行时,它就是一个进程,进程所指包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的,线程是程序中的一个执行流, ...

  7. [JavaEE] Eclipse中web-inf和meta-inf文件夹的信息

    WEB-INF    /WEB-INF/web.xml        你的Web应用程序配置文件,这是一个XML文件,其中描述了 servlet 和其他的应用组件配置及命名规则:    /WEB- I ...

  8. TCP/IP协议原理与应用笔记27:网际协议(IP)之 选项(Options)

    1. 选项(Options) (1)作用:网络测试或者调试,可选 (2)格式:0~40 bytes 2. 选项类型:

  9. MySQL(26):事务的隔离级别出现问题之 幻读

    1. 幻读 幻读(Phantom Read)又称为虚读,是指在一个事务内两次查询中数据条数不一致,幻读和不重复读有些类型,同样是在两次查询过程中,不同的是,幻读是由于其他事务做了插入记录的操作,导致记 ...

  10. Java克隆--深克隆与浅克隆的区别

    克隆,就是复制一个对象的副本,而克隆又分浅克隆和深克隆.浅克隆是指克隆得到的对象基本类型的值改变了,而源对象的值不会变.但如果被克隆对象引用类型的值改变了,那么源对象的值同样会改变,因为引用类型在栈内 ...