[转]iOS为UILabel添加长按复制功能
在iOS中下面三個控件,自身就有復制-粘貼的功能:
?1、UITextView
?2、UITextField
?3、UIWebView
?
UIKit framework提供了幾個類和協(xié)議方便我們在自己的應用程序中實現(xiàn)剪貼板的功能。
?1、UIPasteboard:我們可以向其中寫入數(shù)據(jù),也可以讀取數(shù)據(jù)
?2、UIMenuController:顯示一個快捷菜單,用來展示復制、剪貼、粘貼等選擇的項。
?3、UIResponder中的 canPerformAction:withSender:用于控制哪些命令顯示在快捷菜單中。
?4、當快捷菜單上的命令點擊的時候,UIResponderStandardEditActions將會被調用。
?下面這些項能被放置到剪貼板中
?1、UIPasteboardTypeListString?— ? 字符串數(shù)組, 包含kUTTypeUTF8PlainText
?2、UIPasteboardTypeListURL?— ? URL數(shù)組,包含kUTTypeURL
?3、UIPasteboardTypeListImage?— ? 圖形數(shù)組, 包含kUTTypePNG 和kUTTypeJPEG
?4、UIPasteboardTypeListColor?— ? 顏色數(shù)組
?剪貼板的類型分為兩種:
?系統(tǒng)級:使用UIPasteboardNameGeneral和UIPasteboardNameFind,系統(tǒng)級應用程序關閉,或者卸載的數(shù)據(jù)不會丟失。
?應用程序級:通過設置,可以讓數(shù)據(jù)在應用程序關閉之后仍然保存在剪貼板中,但是應用程序卸載之后數(shù)據(jù)就會失去。我們可用通過pasteboardWithName:create:來創(chuàng)建。
?
例子如下:
有時候我們可能需要復制UILabel上的文本,或者UIImageView的圖片,而UILabel和UIImageView默認是不響應Touch事件的,也無法復制,那么我們就需要自己實現(xiàn)一個可復制的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:)); }?
?
//針對于響應方法的實現(xiàn) -(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數(shù)設為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,創(chuàng)建一個新的viewController,放兩個imageView,默認顯示不同的圖:
然后把上面的代碼直接拷過來,改三個地方:
?UIPasteboard有系統(tǒng)級別和應用級別兩種類型,所以不僅可以在應用程序內通信,還能在應用程序間通信,比如我復制一個url,然后打開safari,粘貼到地址欄去,而我們可以在應用程序間通信、共享數(shù)據(jù)。
在PasteBoardWrite里面點“寫入”后把textField中的文本寫入粘貼板,然后切換到PasteBoardRead的時候顯示出來。如果我們的粘貼板只想給“自己人”用的話,就不能用系統(tǒng)的通用粘貼板,需要我們自己創(chuàng)建一個:
使用這個粘貼板,我們可以把文本存進去,然后在另一個app里面讀出來,一些常用的類型已經被設置為屬性了:?
除此之外,如果是能夠轉換成plist的數(shù)據(jù)類型(NSString, NSArray, NSDictionary, NSDate, NSNumber 和 NSURL),我們可以調用setValue:forPasteboardType:方法去存儲數(shù)據(jù),其他類型只能調用setData:forPasteboardType:方法(plist數(shù)據(jù)類型也可使用),類似于這樣:
?
//存儲數(shù)據(jù) 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,這是一個統(tǒng)一類型標識符(Uniform Type Identifier ?UTI),能幫助app獲取自己能處理的數(shù)據(jù)。比如你只能處理文本的粘貼,那給你一個UIImage顯然是無用的。你可以使用公用的UTI,也可以使用任意字符,蘋果建議使用倒寫的域名加上類型名:com.myCompany.myApp.myType。
轉載于:https://www.cnblogs.com/zhaoyanpeng/p/5282693.html
總結
以上是生活随笔為你收集整理的[转]iOS为UILabel添加长按复制功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA 获取文件的MD5值大小以及常见
- 下一篇: PingUtil in Android