Label--自定義可貼上複製的Label

江湖hi客發表於2016-08-01
在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:來建立。

新建立一個類:CopyLabel

CopyLabel.h檔案

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger,CopyLabelStatus) {
    COPY_PASTE_LABEL,  //有複製和貼上功能label
    COPY_LABEL //只有複製功能label
};

@interface CopyLabel : UILabel
//建立Label時可根據不同的型別來實現不同的功能
@property (nonatomic, assign) CopyLabelStatus labelType;
@end


CopyLabel.m檔案

#import "CopyLabel.h"

@implementation CopyLabel

//通過正常建立的初始化方法,繫結事件
- (id)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self){
        [self attachTapHandler];
    }
    return self;
}

////通過xib檔案建立的初始化方法,繫結事件
-(void)awakeFromNib{
    [super awakeFromNib];
    [self attachTapHandler];
}

//為了能接收到事件(能成為第一響應者),我們需要覆蓋一個方法:
-(BOOL)canBecomeFirstResponder{
    return YES;
}

// 可以響應的方法
//此方法中只相應了複製和貼上兩個方法,也就是彈出的皮膚中只有複製和貼上兩個按鈕。
//其它方法都返回No代表禁止,皮膚內不會出現相應的按鈕。
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender{
    switch (self.labelType) {
        case COPY_PASTE_LABEL:
            //允許複製操作、貼上操作
            if (action == @selector(paste:)) {
                return (action == @selector(paste:));
            }else if (action == @selector(copy:)){
                return (action == @selector(copy:));
            }
            break;
        case COPY_LABEL:
            //只允許複製操作
            return (action == @selector(copy:));
            break;
        default:
            break;
    }
    //其它操作不允許
    return NO;
}

//針對於響應方法的實現,點選copy按鈕時呼叫此方法
-(void)copy:(id)sender{
    UIPasteboard *pboard = [UIPasteboard generalPasteboard];
    pboard.string = self.text;
}
//針對於響應方法的實現,點選paste按鈕時呼叫此方法
-(void)paste:(id)sender{
    UIPasteboard *pboard = [UIPasteboard generalPasteboard];
    self.text = pboard.string;
}

//有了以上三個方法,我們就能處理copy和paste了,當然,在能接收到事件的情況下:
//UILabel預設是不接收事件的,我們需要自己新增touch事件
-(void)attachTapHandler{
    self.userInteractionEnabled = YES;  //使用者互動的總開關
    UILongPressGestureRecognizer * longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    [self addGestureRecognizer:longPress];
}

//接下來,我們需要處理這個tap,以便讓選單欄彈出來:
-(void)handleTap:(UIGestureRecognizer*) recognizer{
    //if判斷是為了保證長按手勢只執行一次
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        [self becomeFirstResponder];
        [[UIMenuController sharedMenuController] setTargetRect:self.frame inView:self.superview];
        [[UIMenuController sharedMenuController] setMenuVisible:YES animated: YES];
    }
}
//這樣一來,一個可複製的UILabel就誕生了!它能處理接收點選、彈出選單欄、處理copy,這是一個很普通的可複製控制元件。
@end



相關文章