iOS開發(fā) UIPasteboard粘貼板全解

UIPasteboard 是 Swift 中用于存儲和檢索應(yīng)用程序中剪貼板中的數(shù)據(jù)的一個類船庇。剪貼板是應(yīng)用程序之間共享數(shù)據(jù)的一種機(jī)制屁使,UIPasteboard 提供了一種簡單的方式來存儲和檢索應(yīng)用程序中的剪貼板數(shù)據(jù)。

下面是 UIPasteboard 的一些特點和用法:

  1. UIPasteboard 是一個公共類別源梭,因此可以從所有應(yīng)用程序中訪問官套。
  2. UIPasteboard 包含兩個方法:setString:和 stringForType:,用于將字符串添加到剪貼板中或從剪貼板中檢索字符串蜀备。
  3. UIPasteboard 還包含一些類型和方法,如 URL 類型杖小、data 類型肆汹、image 類型和 text 類型,用于存儲和檢索不同類型的數(shù)據(jù)予权。
  4. 可以使用 UIPasteboard 將數(shù)據(jù)添加到剪貼板中昂勉,例如將一個 URL 添加到剪貼板中,以便在其他應(yīng)用程序中打開該 URL扫腺。
  5. 可以使用 UIPasteboard 檢索剪貼板中的數(shù)據(jù)岗照,例如檢索剪貼板中的 URL,或檢索剪貼板中的文本。
  6. UIPasteboard 還提供了一些方法攒至,用于檢查剪貼板中是否有特定類型的數(shù)據(jù)厚者,例如檢查剪貼板中是否有文本或 URL。
    下面是一個簡單的示例迫吐,演示如何使用 UIPasteboard 存儲和檢索剪貼板中的數(shù)據(jù):

let string = "Hello, World!"  
let pasteboard = UIPasteboard.general

pasteboard.setString(string, forType: .text)  
print("剪貼板中的內(nèi)容是:\(string)")

if let string = pasteboard.string {  
    print("剪貼板中的內(nèi)容是:\(string)")  
}



在iOS中,UITextField库菲、UITextView和UIWebView等都有復(fù)制粘貼等功能。而其她控件卻沒有集成這些方便操作的功能志膀。下面我將通過對粘貼板UIPasteboard這個類來詳細(xì)說明在iOS中粘貼板的使用方法熙宇。


1、剪切板管理類UIPasteboard詳解

UIPasteboard類有3個初始化方法溉浙,如下:

//獲取系統(tǒng)級別的剪切板
+ (UIPasteboard *)generalPasteboard;
//獲取一個自定義的剪切板 name參數(shù)為此剪切板的名稱 create參數(shù)用于設(shè)置當(dāng)這個剪切板不存在時 是否進(jìn)行創(chuàng)建
+ (nullable UIPasteboard *)pasteboardWithName:(NSString *)pasteboardName create:(BOOL)create;
//獲取一個應(yīng)用內(nèi)可用的剪切板
+ (UIPasteboard *)pasteboardWithUniqueName;

上面3個初始化方法奇颠,分別獲取或創(chuàng)建3個級別不同的剪切板,下面我們詳解一下在什么情況下用哪種初始化方法

+ (UIPasteboard *)generalPasteboard;系統(tǒng)級別的剪切板在整個設(shè)備中共享放航,即是應(yīng)用程序被刪掉烈拒,其向系統(tǒng)級的剪切板中寫入的數(shù)據(jù)依然在。

+ (nullable UIPasteboard *)pasteboardWithName:(NSString *)pasteboardName create:(BOOL)create;自定義的剪切板通過一個特定的名稱字符串進(jìn)行創(chuàng)建广鳍,它在應(yīng)用程序內(nèi)或者同一開發(fā)者開發(fā)的其他應(yīng)用程序中可以進(jìn)行數(shù)據(jù)共享荆几。舉個例子:比如你開發(fā)了多款應(yīng)用,用戶全部下載了赊时,在A應(yīng)用中用戶拷貝了一些數(shù)據(jù)(為了數(shù)據(jù)安全吨铸,不用系統(tǒng)級別的Pasteboard),在打開B應(yīng)用時就會自動識別祖秒,提高用戶體驗诞吱。

+ (UIPasteboard *)pasteboardWithUniqueName;第3個方法創(chuàng)建的剪切板等價為使用第2個方法創(chuàng)建的剪切板,只是其名稱字符串為nil竭缝,它通常用于當(dāng)前應(yīng)用內(nèi)部房维。(當(dāng)然也可以跨應(yīng)用使用,但必須Bundle Identifier 例com.maoshaoqian.** 星號前部一樣)

注意:使用第3個方法創(chuàng)建的剪切板默認(rèn)是不進(jìn)行數(shù)據(jù)持久化的抬纸,及當(dāng)應(yīng)用程序退出后咙俩,剪切板中內(nèi)容將別抹去。若要實現(xiàn)持久化湿故,需要設(shè)置persistent屬性為YES阿趁。

下面我們來看一下UIPasteboard的常用屬性


//剪切板的名稱
@property(readonly,nonatomic) NSString *name;
//根據(jù)名稱刪除一個剪切板
+ (void)removePasteboardWithName:(NSString *)pasteboardName;
//是否進(jìn)行持久化
@property(getter=isPersistent,nonatomic) BOOL persistent;
//此剪切板的改變次數(shù) 系統(tǒng)級別的剪切板只有當(dāng)設(shè)備重新啟動時 這個值才會清零
@property(readonly,nonatomic) NSInteger changeCount;

UIPasteboard數(shù)據(jù)類型判斷及其存取


//獲取剪切板中最新數(shù)據(jù)的類型
- (NSArray<NSString *> *)pasteboardTypes;
//獲取剪切板中最新數(shù)據(jù)對象是否包含某一類型的數(shù)據(jù)
- (BOOL)containsPasteboardTypes:(NSArray<NSString *> *)pasteboardTypes;
//將剪切板中最新數(shù)據(jù)對象某一類型的數(shù)據(jù)取出
- (nullable NSData *)dataForPasteboardType:(NSString *)pasteboardType;
//將剪切板中最新數(shù)據(jù)對象某一類型的值取出
- (nullable id)valueForPasteboardType:(NSString *)pasteboardType;
//為剪切板中最新數(shù)據(jù)對應(yīng)的某一數(shù)據(jù)類型設(shè)置值
- (void)setValue:(id)value forPasteboardType:(NSString *)pasteboardType;
//為剪切板中最新數(shù)據(jù)對應(yīng)的某一數(shù)據(jù)類型設(shè)置數(shù)據(jù)
- (void)setData:(NSData *)data forPasteboardType:(NSString *)pasteboardType;

多組數(shù)據(jù)對象的存取:


//數(shù)據(jù)組數(shù)
@property(readonly,nonatomic) NSInteger numberOfItems;
//獲取一組數(shù)據(jù)對象包含的數(shù)據(jù)類型
- (nullable NSArray *)pasteboardTypesForItemSet:(nullable NSIndexSet*)itemSet;
//獲取一組數(shù)據(jù)對象中是否包含某些數(shù)據(jù)類型
- (BOOL)containsPasteboardTypes:(NSArray<NSString *> *)pasteboardTypes inItemSet:(nullable NSIndexSet *)itemSet;
//根據(jù)數(shù)據(jù)類型獲取一組數(shù)據(jù)對象
- (nullable NSIndexSet *)itemSetWithPasteboardTypes:(NSArray *)pasteboardTypes;
//根據(jù)數(shù)據(jù)類型獲取一組數(shù)據(jù)的值
- (nullable NSArray *)valuesForPasteboardType:(NSString *)pasteboardType inItemSet:(nullable NSIndexSet *)itemSet;
//根據(jù)數(shù)據(jù)類型獲取一組數(shù)據(jù)的NSData數(shù)據(jù)
- (nullable NSArray *)dataForPasteboardType:(NSString *)pasteboardType inItemSet:(nullable NSIndexSet *)itemSet;
//所有數(shù)據(jù)對象
@property(nonatomic,copy) NSArray *items;
//添加一組數(shù)據(jù)對象
- (void)addItems:(NSArray<NSDictionary<NSString *, id> *> *)items;

上面方法中很多需要傳入數(shù)據(jù)類型參數(shù)坛猪,這些參數(shù)是系統(tǒng)定義好的一些字符竄脖阵,如下:

//所有字符串類型數(shù)據(jù)的類型定義字符串?dāng)?shù)組
UIKIT_EXTERN NSArray<NSString *> *UIPasteboardTypeListString;
//所有URL類型數(shù)據(jù)的類型定義字符串?dāng)?shù)組
UIKIT_EXTERN NSArray<NSString *> *UIPasteboardTypeListURL;
//所有圖片數(shù)據(jù)的類型定義字符串?dāng)?shù)據(jù)
UIKIT_EXTERN NSArray<NSString *> *UIPasteboardTypeListImage;
//所有顏色數(shù)據(jù)的類型定義字符串?dāng)?shù)組
UIKIT_EXTERN NSArray<NSString *> *UIPasteboardTypeListColor;

相比于上面兩組方法,下面這些方法更加面向?qū)ο笫裕陂_發(fā)中使用更加方便與快捷:


//獲取或設(shè)置剪切板中的字符串?dāng)?shù)據(jù)
@property(nullable,nonatomic,copy) NSString *string;
//獲取或設(shè)置剪切板中的字符串?dāng)?shù)組
@property(nullable,nonatomic,copy) NSArray<NSString *> *strings;
//獲取或設(shè)置剪切板中的URL數(shù)據(jù)
@property(nullable,nonatomic,copy) NSURL *URL;
//獲取或設(shè)置剪切板中的URL數(shù)組
@property(nullable,nonatomic,copy) NSArray<NSURL *> *URLs;
//獲取或s何止剪切板中的圖片數(shù)據(jù)
@property(nullable,nonatomic,copy) UIImage *image;
//獲取或設(shè)置剪切板中的圖片數(shù)組
@property(nullable,nonatomic,copy) NSArray<UIImage *> *images;
//獲取或設(shè)置剪切板中的顏色數(shù)據(jù)
@property(nullable,nonatomic,copy) UIColor *color;
//獲取或設(shè)置剪切板中的顏色數(shù)組
@property(nullable,nonatomic,copy) NSArray<UIColor *> *colors;

//部分代碼參考

- (BOOL)canBecomeFirstResponder {
    
    return YES;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
        //action 會返回很多命黔,想用哪個就寫那個(action == @selector(cut:) )
    return (action == @selector(copy:) || action == @selector(paste:) );
}

-(void)copy:(id)sender{
    
    UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
    [pasteboard setImage:self.image];
    if ([self.delegate respondsToSelector:@selector(transSomeTing:)]) {
        [self.delegate transSomeTing:pasteboard.image];
        NSLog(@"%@",self.image);
    }
    NSLog(@"您點擊的是拷貝%@",pasteboard.items);
}

-(void)paste:(id)sender{
    
    UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
    UIImage *image = [pasteboard image];
    if (image) {
        self.image = image;
    }
    NSLog(@"您點擊的是粘貼");
}

- (void)cut:(id)sender {
    
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    [pasteboard setImage:self.image];
    NSLog(@"您點擊的是剪切");
}

- (void)select:(id)sender {
    
    NSLog(@"您點擊的是選擇");
}

-(void)selectAll:(id)sender {
    
    NSLog(@"您點擊的是全選");
}


對剪切板的某些操作會觸發(fā)如下通知:


//剪切板內(nèi)容發(fā)生變化時發(fā)送的通知
UIKIT_EXTERN NSString *const UIPasteboardChangedNotification;
//剪切板數(shù)據(jù)類型鍵值增加時發(fā)送的通知
UIKIT_EXTERN NSString *const UIPasteboardChangedTypesAddedKey;
//剪切板數(shù)據(jù)類型鍵值移除時發(fā)送的通知
UIKIT_EXTERN NSString *const UIPasteboardChangedTypesRemovedKey;
//剪切板被刪除時發(fā)送的通知
UIKIT_EXTERN NSString *const UIPasteboardRemovedNotification;
//使用舉例
//當(dāng)剪切板被刪除時呜呐,監(jiān)聽通知,可處理相應(yīng)事件纷铣;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuControllerWillHide) name:UIPasteboardRemovedNotification object:nil];


2、剪切板管理類UIPasteboard具體使用

我們以系統(tǒng)粘貼板+ (UIPasteboard *)generalPasteboard;來舉例子
我們給UIImageView添加復(fù)制粘貼事件


//
//  ViewController.m
//  Practice_UIPasteboard
//
//

#import "ViewController.h"
#import "PasteboardLabel.h"
#import "PasteboardImageView.h"
#import <MobileCoreServices/MobileCoreServices.h>

@interface ViewController ()<transSometing>

@property (strong, nonatomic) IBOutlet PasteboardImageView *leftImageView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.leftLabel.userInteractionEnabled = YES;
//用于監(jiān)聽 UIMenuController的變化
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuControllerWillShow) name:UIMenuControllerWillShowMenuNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuControllerWillHide) name:UIMenuControllerWillHideMenuNotification object:nil];
    // Do any additional setup after loading the view, typically from a nib.
}

- (IBAction)longPressGestureAction:(UILongPressGestureRecognizer *)sender {
    
//要將圖片變?yōu)榈谝豁憫?yīng)者战转,而且要把圖片設(shè)為**可交換狀態(tài)**
        [self.leftImageView becomeFirstResponder];
        self.leftImageView.userInteractionEnabled = YES;
        self.leftImageView.delegate = self;
        UIMenuController *menuController = [UIMenuController sharedMenuController];
        [menuController setTargetRect:self.leftImageView.frame inView:self.view];
        [menuController setMenuVisible:YES animated:YES];
    }

}
//  PasteboardImageView.m
//  Practice_UIPasteboard
//
//

#import "PasteboardImageView.h"

@implementation PasteboardImageView

//這個方法不能少
- (BOOL)canBecomeFirstResponder {
    
    return YES;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
        
    return (action == @selector(copy:) || action == @selector(paste:) );
}

-(void)copy:(id)sender{
    
    UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
    [pasteboard setImage:self.image];
    if ([self.delegate respondsToSelector:@selector(transSomeTing:)]) {
        [self.delegate transSomeTing:pasteboard.image];
        NSLog(@"%@",self.image);
    }
    NSLog(@"您點擊的是拷貝%@",pasteboard.items);
}

-(void)paste:(id)sender{
    
    UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
    UIImage *image = [pasteboard image];
    if (image) {
        self.image = image;
    }
    NSLog(@"您點擊的是粘貼");
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搜立,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子槐秧,更是在濱河造成了極大的恐慌啄踊,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刁标,死亡現(xiàn)場離奇詭異颠通,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)膀懈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門顿锰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人启搂,你說我怎么就攤上這事硼控。” “怎么了胳赌?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵牢撼,是天一觀的道長。 經(jīng)常有香客問我疑苫,道長熏版,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任捍掺,我火速辦了婚禮撼短,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挺勿。我一直安慰自己阔加,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布满钟。 她就那樣靜靜地躺著胜榔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪湃番。 梳的紋絲不亂的頭發(fā)上夭织,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音吠撮,去河邊找鬼尊惰。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弄屡。 我是一名探鬼主播题禀,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼膀捷!你這毒婦竟也來了迈嘹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤全庸,失蹤者是張志新(化名)和其女友劉穎秀仲,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體壶笼,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡神僵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了覆劈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片保礼。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖责语,靈堂內(nèi)的尸體忽然破棺而出氓英,到底是詐尸還是另有隱情,我是刑警寧澤鹦筹,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布铝阐,位于F島的核電站,受9級特大地震影響铐拐,放射性物質(zhì)發(fā)生泄漏徘键。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一遍蟋、第九天 我趴在偏房一處隱蔽的房頂上張望吹害。 院中可真熱鬧,春花似錦虚青、人聲如沸它呀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纵穿。三九已至,卻和暖如春奢人,著一層夾襖步出監(jiān)牢的瞬間谓媒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工何乎, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留句惯,地道東北人土辩。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像抢野,于是被迫代替她去往敵國和親拷淘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容