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。

IOS 为UILabel添加长按复制功能的更多相关文章

  1. 给文本标签UILabel添加长按复制功能

    http://www.111cn.net/sj/iOS/104236.htm http://blog.csdn.net/lrenjun/article/details/12582927 自定义一个可复 ...

  2. ios label 简单的长按复制文本信息

    在iOS开发过程中,有时候会用到UILabel展示的内容,那么就设计到点击UILabel复制它上面展示的内容的功能,也就是Label长按复制功能.网上有很多种给Label添加长按复制功能的方法,这里我 ...

  3. iOS开发 UILabel实现自适应高宽

    UILabel是iOS开发常用的控件.UILabel的属性需要了解,UILabel的特殊显示效果也需要我们掌握.UILabel自适应高宽度是很多初学者遇到的技术性难题.比如段文字,要让他完全地分行显示 ...

  4. iOS关于UILabel 基本属性 背景图片 背景色

    [代码] iOS关于UILabel 基本属性 背景图片 背景色 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ...

  5. 向IOS模拟机上添加图片

    [问题] 折腾: 关于iOS/iPhone中的文件选择对话框,用于用户去选择图片等文件 的过程中,遇到个问题,希望程序提供用户选择自己想要的图片作为Bird的图片. 但是当前开发环境是iOS模拟器,所 ...

  6. UILabel添加图片之富文本的简单应用

    若想对UILabel添加图片,那么就需要使用NSMutableAttributedString来定义先定义一个普通的label UILabel *lab = [[UILabel alloc]initW ...

  7. 李洪强iOS开发之添加手势

    李洪强iOS开发之添加手势 02 - 添加手势

  8. Xamarin iOS教程之添加和定制视图

    Xamarin iOS教程之添加和定制视图 Xamarin iOS用户界面——视图 在iPhone或者iPad中,用户看到的摸到的都是视图.视图是用户界面的重要组成元素.例如,想要让用户实现文本输入时 ...

  9. iOS 设置UILabel 的内边距

    iOS 设置UILabel 的内边距 - (void)drawTextInRect:(CGRect)rect { UIEdgeInsets insets = {, , , }; [super draw ...

随机推荐

  1. IDA Pro使用技巧及大杂烩

    IDA Pro使用技巧及大杂烩 IDA Pro基本简介 IDA加载完程序后,3个立即可见的窗口分别为IDA-View,Named,和消息输出窗口(output Window). IDA图形视图会有执行 ...

  2. FZOJ Problem 2103 Bin & Jing in wonderland

                                                                                                        ...

  3. 基于promise和script标签的jsonp

    function Jsonp(url){ var url=url.indexOf('?')>-1?url+"&callback=callback":url+" ...

  4. 【dll】关于__declspec的简记,由两个单词缩写而来!(转)

    关于declspec的一点说明 我遇到这个单词总觉得记不住,时间一长就忘了.今天在复习dll的时候又遇到了这个单词,我感觉应该是两个单词的缩写,但又不敢确定,特地发帖网上求助,得到两位高手的帮助.下面 ...

  5. Linux 之 用户及用户组

    用户及用户组 参考教程:[千峰教育] 命令: whoami: 作用:查看当前登录的用户. 格式:whoami /etc/passwd: 说明:该文件存放了系统中所有的用户,每一行的每一列如下: 用户名 ...

  6. LeetCode OJ——Word Break

    http://oj.leetcode.com/problems/word-break/ 动态规划题目,重点是建立出模型来: fun(start,end) = fun(start,i)*fun(i+1, ...

  7. 两个 DataTable 读取重复数据

    今天正好用到Excel 导入转换成table , 文件中数据要和数据库里数据进行比对,有重复的抛出重复数据. 和大家分享下,欢迎高手留言指点.有问题可以留言关注! /// <summary> ...

  8. AC日记——爱情之路 codevs 2070

    2070 爱情之路  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description yh非常想念他的女朋友小y,于是他 ...

  9. HOJ - 2543最小费用流

    题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=2543 这个题目挺有意思. 自己扣了一会儿,发现图挺好建,就把(u,v,f,w) 拆成(u,v,f,0) ...

  10. js-斐波那切数列

    f(1) = 1; f(2) = 1; f(3) = f(1) + f(2) = 2; f(4) = f(3) + f(2) = 3; f(5) = f(4) + f(3) = 5; f(6) = f ...