[转]iOS为UILabel添加长按复制功能
在iOS中下面三个控件,自身就有复制-粘贴的功能:
1、UITextView
2、UITextField
3、UIWebView
UIKit framework提供了几个类和协议方便我们在自己的应用程序中实现剪贴板的功能。
1、UIPasteboard:我们可以向其中写入数据,也可以读取数据
2、UIMenuController:显示一个快捷菜单,用来展示复制、剪贴、粘贴等选择的项。
3、UIResponder中的 canPerformAction:withSender:用于控制哪些命令显示在快捷菜单中。
4、当快捷菜单上的命令点击的时候,UIResponderStandardEditActions将会被调用。
下面这些项能被放置到剪贴板中
1、UIPasteboardTypeListString — 字符串数组, 包含kUTTypeUTF8PlainText
2、UIPasteboardTypeListURL — URL数组,包含kUTTypeURL
3、UIPasteboardTypeListImage — 图形数组, 包含kUTTypePNG 和kUTTypeJPEG
4、UIPasteboardTypeListColor — 颜色数组
剪贴板的类型分为两种:
系统级:使用UIPasteboardNameGeneral和UIPasteboardNameFind,系统级应用程序关闭,或者卸载的数据不会丢失。
应用程序级:通过设置,可以让数据在应用程序关闭之后仍然保存在剪贴板中,但是应用程序卸载之后数据就会失去。我们可用通过pasteboardWithName:create:来创建。
例子如下:
有时候我们可能需要复制UILabel上的文本,或者UIImageView的图片,而UILabel和UIImageView默认是不响应Touch事件的,也无法复制,那么我们就需要自己实现一个可复制的UILabel。新添加一个类继承自UILabel:
@interface UICopyLabel : UILabel @end #import "UICopyLabel.h" @implementation UICopyLabel @end
为了能接收到事件(能成为第一响应者),我们需要覆盖一个方法:
-(BOOL)canBecomeFirstResponder { return YES; }
还需要针对复制的操作覆盖两个方法:
// 可以响应的方法 -(BOOL)canPerformAction:(SEL)action withSender:(id)sender { return (action == @selector(copy:)); }
//针对于响应方法的实现 -(void)copy:(id)sender { UIPasteboard *pboard = [UIPasteboard generalPasteboard]; pboard.string = self.text; }
有了以上三个方法,我们就能处理copy了,当然,在能接收到事件的情况下:
//UILabel默认是不接收事件的,我们需要自己添加touch事件 -(void)attachTapHandler { self.userInteractionEnabled = YES; //用户交互的总开关 UITapGestureRecognizer *touch = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; touch.numberOfTapsRequired = 2; [self addGestureRecognizer:touch]; [touch release]; } //绑定事件 - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self){ [self attachTapHandler]; } return self; } //同上 -(void)awakeFromNib { [super awakeFromNib]; [self attachTapHandler]; }
我们已经可以接收到事件了!由于我在上方将tap数设为2,所以需要双击才能捕获,接下来,我们需要处理这个tap,以便让菜单栏弹出来:
-(void)handleTap:(UIGestureRecognizer*) recognizer { [self becomeFirstResponder];UIMenuItem *copyLink = [[[UIMenuItemalloc] initWithTitle:@"复制"action:@selector(copy:)]autorelease];[[UIMenuControllersharedMenuController] setMenuItems:[NSArrayarrayWithObjects:copyLink, nil]];[[UIMenuControllersharedMenuController] setTargetRect:self.frameinView:self.superview];[[UIMenuControllersharedMenuController] setMenuVisible:YESanimated: YES]; }
这样一来,一个可复制的UILabel就诞生了!它能处理接收点击、弹出菜单栏、处理copy,这是一个很普通的可复制控件。
接下来我们做一个可复制的UIImageView,创建一个新的viewController,放两个imageView,默认显示不同的图:
然后把上面的代码直接拷过来,改三个地方:
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender { return (action == @selector(copy:) || action == @selector(paste:)); } -(void)copy:(id)sender { UIPasteboard *pboard = [UIPasteboard generalPasteboard]; pboard.image = self.image; } -(void)paste:(id)sender { UIPasteboard *pboard = [UIPasteboard generalPasteboard]; self.image = pboard.image; }
UIPasteboard有系统级别和应用级别两种类型,所以不仅可以在应用程序内通信,还能在应用程序间通信,比如我复制一个url,然后打开safari,粘贴到地址栏去,而我们可以在应用程序间通信、共享数据。
在PasteBoardWrite里面点“写入”后把textField中的文本写入粘贴板,然后切换到PasteBoardRead的时候显示出来。如果我们的粘贴板只想给“自己人”用的话,就不能用系统的通用粘贴板,需要我们自己创建一个:
//需要提供一个唯一的名字,一般使用倒写的域名:com.mycompany.myapp.pboard //后面的参数表示,如果不存在,是否创建一个 UIPasteboard *pb = [UIPasteboard pasteboardWithName:@"testBoard" create:YES];
使用这个粘贴板,我们可以把文本存进去,然后在另一个app里面读出来,一些常用的类型已经被设置为属性了:
除此之外,如果是能够转换成plist的数据类型(NSString, NSArray, NSDictionary, NSDate, NSNumber 和 NSURL),我们可以调用setValue:forPasteboardType:方法去存储数据,其他类型只能调用setData:forPasteboardType:方法(plist数据类型也可使用),类似于这样:
//存储数据 NSDictionary *dict = [NSDictionary dictionaryWithObject:textField.text forKey:@"content"]; NSData *dictData = [NSKeyedArchiver archivedDataWithRootObject:dict]; [pb setData:dictData forPasteboardType:@"myType"]; //获取就类似于这样: UIPasteboard *pb = [UIPasteboard pasteboardWithName:@"testBoard" create:YES]; NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:[pb dataForPasteboardType:@"myType"]]; caption.text = [dict objectForKey:@"content"];
上面提到了一个PasteboardType,这是一个统一类型标识符(Uniform Type Identifier UTI),能帮助app获取自己能处理的数据。比如你只能处理文本的粘贴,那给你一个UIImage显然是无用的。你可以使用公用的UTI,也可以使用任意字符,苹果建议使用倒写的域名加上类型名:com.myCompany.myApp.myType。
转载于:https://www.cnblogs.com/zhaoyanpeng/p/5282693.html
[转]iOS为UILabel添加长按复制功能相关推荐
- IOS 为UILabel添加长按复制功能
IOS 为UILabel添加长按复制功能 在iOS中下面三个控件,自身就有复制-粘贴的功能: 1.UITextView 2.UITextField 3.UIWebView UIKit framewor ...
- iOS swift5 UIlabel添加下滑线
lazy var privacyPolicyBtn:UIButton = {let btn = UIButton(type: .custom)btn.addTarget(self, action: # ...
- iOS开发 UILabel实现自适应高宽
UILabel是iOS开发常用的控件.UILabel的属性需要了解,UILabel的特殊显示效果也需要我们掌握.UILabel自适应高宽度是很多初学者遇到的技术性难题.比如段文字,要让他完全地分行显示 ...
- 代码雨代码源复制_小程序基于Parser添加长按复制、代码高亮等功能
程序员技术之旅网站/小程序/公众号进入小程序 功能展示 引入Parser 微信小程序中引入Parser可直接在GitHub项目主页(https://github.com/jin-yufeng/Pars ...
- 移动端」H5页面长按复制功能实现
默认情况下禁止了长按复制功能,要此功能需要增加css声明: user-select 属性规定是否能选取元素的文本. 在 web 浏览器中,如果您在文本上双击,文本会被选取或高亮显示.此属性用于阻止这种 ...
- 微信小程序怎么长按复制_微信小程序基于Parser添加长按复制、代码高亮等功能...
功能展示 引入Parser 微信小程序中引入Parser可直接在项目主页查阅. 代码高亮 高亮插件 Prism官网下载prism.js和prism.css,默认只有css代码有渲染样式,注意选择需要渲 ...
- 移动端(ios and android)长按识别二维码(含js与原生互调)
这篇文章就整理下移动端长按识别二维码的实现吧!实现方式可以分为三种 一.长按原生控件,直接获取控件中的图片数据(src或background) 二.长按原生控件,截图识别 三.长按web中的图片,ap ...
- android textview 长按事件,利用TextView怎么实现一个长按复制功能
利用TextView怎么实现一个长按复制功能 发布时间:2020-12-03 16:31:11 来源:亿速云 阅读:67 作者:Leah 利用TextView怎么实现一个长按复制功能?针对这个问题,这 ...
- android彩蛋长按无反应,Android TextView长按复制功能失效解决办法
应用中使用RecyclerView列表来展现动态简介,这时候需要添加长按复制的功能来提升用户的体验.使用Android自带的功能就能满足该需求,无需自己实现,方式很简单,一句话解决: TextView ...
最新文章
- STM32串口第一个字节丢失问题的分析过程
- socket编程之addrinfo结构体与getaddrinfo函数
- “365算法每日学计划”:03打卡-贪心算法
- bzoj1588营业额统计
- ab flash player 8_FLASH 质子治疗的技术挑战
- 大神级的布线,人家攻城狮是如何做到的?
- orcale中case when和group by同时使用会报无效标识符
- 软件设计开发笔记1:基于状态机的程序设计
- 趣文:有趣的 Linux 命令
- WCDMA,CDMA2000,TD_SCDMA
- 校园无盘服务器,校园微机系统优化及无盘改造实例.docx
- mysql添加外键约束的语法_Mysql添加外键约束.
- cholesky分解java代码,实数矩阵Cholesky分解算法的C++实现
- 结合盒子模型,发布一张你的卡片
- Pytorch基础学习(第一章-PyTorch基础概念)
- python第三项基础知识_Python学习心得——基础知识(三)
- CSS世界-第四章 盒尺寸四大家族
- access文件放置服务器,怎么把access数据库放服务器上
- 微信小程序使用前置摄像头拍照
- 笑着离开惠普读书笔记