IOS --关于粘贴板 ,剪切板 ,UILabel的复制

网友投稿 464 2022-11-28

IOS --关于粘贴板 ,剪切板 ,UILabel的复制

在iOS中下面三个控件,自身就有复制-粘贴的功能:

1、UITextView

UITextField

UIWebView

UIKit framework提供了几个类和协议方便我们在自己的应用程序中实现剪贴板的功能。

应用程序级:通过设置,可以让数据在应用程序关闭之后仍然保存在剪贴板中,但是应用程序卸载之后数据就会失去。我们可用通过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];}

-(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。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java 代码实例解析设计模式之监听者模式
下一篇:5G光模块市场的大热可以带来什么
相关文章

 发表评论

暂时没有评论,来抢沙发吧~