[转]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。

时间: 2024-08-06 00:05:23

[转]iOS为UILabel添加长按复制功能的相关文章

IOS 为UILabel添加长按复制功能

IOS 为UILabel添加长按复制功能 在iOS中下面三个控件,自身就有复制-粘贴的功能: 1.UITextView 2.UITextField 3.UIWebView UIKit framework提供了几个类和协议方便我们在自己的应用程序中实现剪贴板的功能. 1.UIPasteboard:我们可以向其中写入数据,也可以读取数据 2.UIMenuController:显示一个快捷菜单,用来展示复制.剪贴.粘贴等选择的项. 3.UIResponder中的 canPerformAction:wi

ios开发-给cell添加长按手势

业务需要给cell添加一个长按手势 //需要在这个方法里添加 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //添加长按手势 UILongPressGestureRecognizer * longPressGesture =[[UILongPressGestureRecognizer alloc]initWithTarget:self a

IOS给tableview的cell添加长按手势执行两次(UILongPressGestureRecognizer)

这里我们为tableview添加长按手势 UILongPressGestureRecognizer *longPressGr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)]; longPressGr.minimumPressDuration = 0.5f; longPressGr.numberOfTouchesRequired = 1; [_tableV

iOS开发 UILabel实现自适应高宽

UILabel是iOS开发常用的控件.UILabel的属性需要了解,UILabel的特殊显示效果也需要我们掌握.UILabel自适应高宽度是很多初学者遇到的技术性难题.比如段文字,要让他完全地分行显示且要让后面的控件不被遮挡.这需要我们的UILabel能够自适应高宽,以便完全显示text的内容,后面的控件可以获取UILabel的起始坐标和宽高来重新设置frame来达到紧贴着UILabel显示而不被遮挡. 工具/原料 Mac OS X操作系统::OS X 10.11.5 编译环境:Xcode 7.

iOS: 学习笔记, 添加一个带界面约束的控制器

1. 创建一个空iOS应用程序(Empty Application). 2. 添加加控制器类. 修改控制器类的viewDidLoad 1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 //创建标题 5 UILabel *header = [[UILabel alloc] init]; 6 header.text = @"欢迎来到我的世界!"; 7 header.textAlignment = NSTextAlignmentCenter

IOS下 UILabel 如何自动换行

转自:http://zasoft.blog.163.com/blog/static/205215176201301414915700/ 背景: 相信很多朋友都遇到过,文本的内容长度不一,需要根据内容的多少来自动换行处理. 场景: 很多APP中评论,有的评论长,有的评论短,有的一行,有的多行. ? 下面以评论的实现为例来说说具体如何实现. ? 技术点: UILabel的自动换行,自动换行的同时要自适应Frame大小. UITableView的行高自适应内容,实时调整高度. 实现方法: UILabe

在iOS App 中添加启动画面

你可以认为你需要为启动画面编写代码,然而Apple 让你可以非常简单地在Xcode中完成.不需要编写代码,你仅需要在Xcode中进行一些配置. 1.什么是启动画面(Splash Screen)? 启动画面是你在启动App的时候看到的第一个界面,通常,启动画面是覆盖整个屏幕的一张图片,在主屏幕装在完后隐藏. 启动画面的主要目的是让用户知道你的App正在装载,并且对用户介绍你的品牌.启动画面对哪些需要较长时间启动的Apps尤其重要.一般而言,启动画面是为了给用户更好的体验. 2.在你的App中添加启

向IOS模拟机上添加图片

[问题] 折腾: 关于iOS/iPhone中的文件选择对话框,用于用户去选择图片等文件 的过程中,遇到个问题,希望程序提供用户选择自己想要的图片作为Bird的图片. 但是当前开发环境是iOS模拟器,所以就涉及到,如何让iOS模拟器中存在图片,以供用户选择. [解决过程] 1. 后来得知iOS模拟器在默认情况下是没有图片的,所以,就要想办法添加图片到iOS模拟器中(的Photos,即Album). 2. 然后参考:Adding images to iPhone Simulator,但是最后却找不到

iOS 运行时添加属性和方法

原文链接http://blog.csdn.net/meegomeego/article/details/18356169第一种:runtime.h里的方法 BOOL class_addProperty(Class cls,constchar*name,constobjc_property_attribute_t*attributes,unsignedint attributeCount) #include <objc/runtime.h> #import <Foundation/Foun