iOS文本編程指南(六)

復(fù)制撼港,剪切,粘貼操作

用戶可以復(fù)制某個(gè)應(yīng)用中的文本营曼,圖片,或者其他數(shù)據(jù)到另外一個(gè)地方愚隧,到該應(yīng)用內(nèi)或者另一個(gè)應(yīng)用都可以蒂阱。UIKit Framework在UITextView中實(shí)現(xiàn)了復(fù)制-剪切-粘貼操作,如果你想要擁有這些行為奸攻,你可以使用這些類或者自己實(shí)現(xiàn)復(fù)制-剪切-粘貼蒜危。

下面的內(nèi)容描述了UIKit的接口虱痕,如何使用復(fù)制睹耐,剪切,粘貼操作部翘。

注:和復(fù)制粘貼操作相關(guān)的指導(dǎo)硝训,看iOS Human Interface Guidelines.中的“Supporting Copy and Paste”一節(jié)

UIKit的復(fù)制粘貼操作

UIKit中提供了幾個(gè)類和一個(gè)非正式協(xié)議(譯者注:非正式協(xié)議在較早的版本用分類實(shí)現(xiàn),目前用協(xié)議實(shí)現(xiàn),協(xié)議中的方法為可選類型)以及一種機(jī)制窖梁,讓你能夠?qū)崿F(xiàn)復(fù)制赘风,剪切,粘貼操作纵刘。

  • UIPasteboard類提供了剪切板:共享數(shù)據(jù)的保存的地方邀窃。這個(gè)類提供了從剪切板按條讀寫數(shù)據(jù)的方法。
  • UIMenuController類展示了編輯菜單假哎,出現(xiàn)在選中內(nèi)容的上方或者下方瞬捕。編輯菜單默認(rèn)的命令是復(fù)制,剪切舵抹,粘貼肪虎,選中和全選。你可以在編輯菜單中添加自定義條目惧蛹。
  • UIResponder類聲明了canPerformAction:withSender:方法扇救。響應(yīng)類可以實(shí)現(xiàn)該方法,來讓某些編輯條目根據(jù)當(dāng)前選中內(nèi)容出現(xiàn)或移除香嗓。
  • UIResponderStandardEditActions 非正式協(xié)議聲明了處理復(fù)制迅腔,剪切,粘貼靠娱,選中以及全選命令的接口钾挟。當(dāng)用戶點(diǎn)擊了一個(gè)命令時(shí),響應(yīng)的方法會被調(diào)用饱岸。(譯者注:UITextView實(shí)現(xiàn)了改協(xié)議)

剪切板

剪切版是應(yīng)用內(nèi)或應(yīng)用間交換數(shù)據(jù)的的標(biāo)準(zhǔn)機(jī)制掺出。其最常見的用處是復(fù)制,剪切苫费,粘貼操作汤锨。

  • 當(dāng)用戶選中了數(shù)據(jù),并且選擇了復(fù)制(或剪切)命令百框,那么被選中的數(shù)據(jù)就被放入了剪切板
  • 當(dāng)用戶選擇了粘貼命令闲礼,在剪切板中的數(shù)據(jù)就被復(fù)制到了當(dāng)前應(yīng)用中。

在iOS中铐维,剪切板也用來支持查找操作柬泽。并且,你可以使用自定義的URL機(jī)制代替復(fù)制嫁蛇,剪切锨并,粘貼操作,讓剪切板在應(yīng)用間傳輸數(shù)據(jù)睬棚。具體信息參照Info.plist的設(shè)置第煮。

拋開具體操作解幼,剪切板的基本功能是往里寫數(shù)據(jù)和從中讀數(shù)據(jù)。雖然概念簡單包警,但是包含了諸多細(xì)節(jié)撵摆。主要復(fù)雜的地方在于數(shù)據(jù)的表達(dá)有多種方式,這種復(fù)雜性就導(dǎo)致了也需要考慮性能害晦。下面就會討論一下這些問題特铝。

命名剪切板

剪切板可能是共有的或是私有的。共有的剪切板被稱作系統(tǒng)剪切板壹瘟,私有的剪切板是應(yīng)用創(chuàng)建的苟呐,因此被稱作應(yīng)用剪切板。剪切板必須擁有一個(gè)唯一的名字俐筋。UIPasteboard定義了兩個(gè)系統(tǒng)剪切板牵素,它們的名字和用處如下:

  • UIPasteboardNameGeneral 涉及多種類型數(shù)據(jù)的剪切,復(fù)制和粘貼操作澄者。你可以通過generalPasteboard 類方法獲取這個(gè)單例笆呆。
  • UIPasteboardNameFind 用作查找操作。用戶在UISearchBar中輸入的字符串會被寫入到該剪切板中粱挡,因此可以在應(yīng)用間共享赠幕。你可以通過調(diào)用 pasteboardWithName:create:類方法,傳入U(xiǎn)IPasteboardNameFind參數(shù)來獲取該對象询筏。

通常你都會使用系統(tǒng)剪切板榕堰,如果有必要你可以通過調(diào)用cpasteboardWithName:create:方法創(chuàng)建你自己的應(yīng)用剪切板。調(diào)用pasteboardWithUniqueName這個(gè)方法也可以嫌套,一個(gè)擁有唯一名字的應(yīng)用剪切板會被創(chuàng)建出來逆屡,名字可以通過剪切板對象的name屬性查看。

剪切板的持久化

剪切板能夠被持久化踱讨。如果剪切板被持久化魏蔗,可以在之前的應(yīng)用退出之后或者系統(tǒng)重啟之后使用。系統(tǒng)剪切板是持久化的痹筛。雖然應(yīng)用剪切板默認(rèn)是不持久化的莺治,你可以通過設(shè)置persistent屬性為YES來使他們變成可持久化的。不持久化的剪切板在應(yīng)用退出時(shí)就沒了帚稠,持久化的剪切板在應(yīng)用卸載時(shí)被移除掉谣旁。

剪切板持有者和條目

最后一次向剪切板中加入數(shù)據(jù)的對象被視作剪切板持有者。每一條向剪切板中加入的數(shù)據(jù)被視作剪切板條目滋早。剪切板可以持有一條或多條條目榄审。應(yīng)用能夠加入和跟蹤任意數(shù)量的條目。例如馆衔,比如一個(gè)用戶選擇了文字+圖片瘟判。他們被復(fù)制到剪切板時(shí)怨绣,文本和圖片作為不同的條目角溃。應(yīng)用讀取多個(gè)條目拷获,可以選擇那些需要支持的(例如,只需要處理文字而不需要處理圖片)减细。

表示與UTI

剪切板操作經(jīng)常是跨應(yīng)用的匆瓜。沒有應(yīng)用可以知道另外一個(gè)應(yīng)用可以處理哪些數(shù)據(jù)。為了最大化這種共享的能力未蝌,剪切板可以對一個(gè)剪切板條目進(jìn)行多種表示驮吱。例如,一個(gè)富文本編輯器可能對一份拷貝數(shù)據(jù)提供了HTML萧吠,PDF和純文本的表示左冬。一個(gè)剪切板條目包括了應(yīng)用所能提供的所有表示。

每一個(gè)剪切板條目通常使用唯一類型標(biāo)識(UTI)纸型。(UTI就是一個(gè)唯一的字符串拇砰,用來標(biāo)記數(shù)據(jù)類型。)UTI提供了一個(gè)統(tǒng)一的標(biāo)記數(shù)據(jù)類型的方式狰腌。如果你有一個(gè)自定義的數(shù)據(jù)類型想要支持除破,你必須為它創(chuàng)建一個(gè)唯一的標(biāo)識。對此琼腔,你可以使用逆向域名來確保唯一性瑰枫,例如,一個(gè)自定義的類型表示可以是com.myCompany.myApp.myType丹莲。更多有關(guān)UTI的內(nèi)容光坝,查看Uniform Type Identifiers Overview

舉個(gè)例子甥材,假設(shè)一個(gè)應(yīng)用支持富文本和圖片的選中教馆。它可能想將富文本的Unicode版本和圖片的多種表示都放到剪切板中。每一個(gè)條目的每種表示被存儲在它自身的數(shù)據(jù)中擂达,如下圖:

通常土铺,為了最大化能夠共享數(shù)據(jù)的可能性,剪切板條目應(yīng)當(dāng)包含盡可能多的表示板鬓。

一個(gè)剪切板的讀者必須找到最合適的數(shù)據(jù)類型悲敷。典型地,這意味著選擇能夠支持的最復(fù)雜類型俭令。例如后德,對于一份拷貝的文本數(shù)據(jù),文本編輯器應(yīng)該提供HTML和普通文本的表示抄腔。一個(gè)能夠支持富文本的應(yīng)用應(yīng)該使用HTML的表示瓢湃,而僅能支持普通文本的應(yīng)用就使用普通文本的版本理张。

改變數(shù)

改變數(shù)是剪切板的變量,每次當(dāng)剪切板的內(nèi)容發(fā)生變化時(shí)绵患,它就增加雾叭。具體指的是剪切板條目加入、修改或者刪除時(shí)落蝙。通過檢查改變數(shù)织狐,應(yīng)用能夠檢查當(dāng)前剪切板中的數(shù)據(jù)是否跟上次獲取到的一致。每次改變數(shù)增加時(shí)筏勒,剪切板會給觀察者發(fā)送通知移迫。

第一步:識別選中并展示編輯菜單

如果你想使用復(fù)制,剪切或者粘貼之類的東西管行,你首先需要選中(一個(gè)粘貼操作通常在一個(gè)空選中上操作厨埋,例如一個(gè)光標(biāo))。在選中一個(gè)條目之后捐顷,你應(yīng)該展示展示編輯菜單荡陷。編輯菜單是一個(gè)系統(tǒng)菜單,它可能包含以下命令:拷貝套菜,剪切亲善,粘貼,選中和全選逗柴。編輯菜單指向被選中內(nèi)容蛹头。當(dāng)用戶點(diǎn)擊一個(gè)菜單項(xiàng)時(shí),協(xié)議UIResponderStandardEditActions中的方法(諸如cut: paste:等方法)就會被調(diào)用戏溺。

獲取更多有關(guān)選中以及菜單的展示管理的內(nèi)容渣蜗,查看Managing the Selection and the Edit Menu

復(fù)制和剪切

當(dāng)用戶點(diǎn)擊復(fù)制后者剪切命令式,系統(tǒng)會調(diào)用相應(yīng)對象的copy:或者cut:方法旷祸。通常是第一響應(yīng)者實(shí)現(xiàn)了這些方法耕拷,如果第一響應(yīng)者沒有實(shí)現(xiàn)這些方法,消息會沿著響應(yīng)鏈傳遞托享。非正式協(xié)議UIResponderStandardEditActions中定義了這些方法骚烧。

注意:任何類可實(shí)現(xiàn)UIResponderStandardEditActions中的方法,但是最好是繼承UIResponder闰围,并在響應(yīng)鏈中的類赃绊。

實(shí)現(xiàn)copy:或者cut:方法時(shí),你應(yīng)該向剪切板中寫入選中數(shù)據(jù)的盡可能多的表達(dá)羡榴。這些操作包括以下步驟(假設(shè)只有一個(gè)剪切板條目):

  1. 從選中對象中獲取數(shù)據(jù)碧查。二進(jìn)制數(shù)據(jù)一定要包在NSData對象中。如果要寫入其他類型的數(shù)據(jù),那么必須是屬性列表對象——也就是說忠售,是如下類型的對象:NSString传惠, NSArray, NSDictionary, NSDate, NSNumber, 或者 NSURL。更多內(nèi)容稻扬,查看Property List Programming Guide

  2. 如果可以卦方,產(chǎn)生一個(gè)或更多該對象或數(shù)據(jù)的表達(dá)。例如腐螟,如果之前選中了一個(gè)UIImage對象愿汰,你可以使用UIImageJPEGRepresentation和UIImagePNGRepresentation函數(shù)來將該圖片轉(zhuǎn)換成不同的表示困后。

  3. 獲取剪切板對象乐纸。通常獲取通用剪切板,調(diào)用 generalPasteboard類方法摇予。

  4. 對于寫入剪切板的條目的每一種表示設(shè)置一個(gè)UTI汽绢。

  5. 寫入數(shù)據(jù)到剪切板的第一個(gè)位置,對于不同的數(shù)據(jù)類型:

    • 如果是數(shù)據(jù)對象侧戴,發(fā)送setData:forPasteboardType: 消息到剪切板對象
    • 如果是屬性列表對象宁昭,發(fā)送setValue:forPasteboardType: 消息到剪切板。
  6. 如果命令是剪切酗宋,從應(yīng)用的數(shù)據(jù)中移除選中的對象并更新你的頁面积仗。

     - (void)copy:(id)sender {
         UIPasteboard *gpBoard = [UIPasteboard generalPasteboard];
         ColorTile *theTile = [self colorTileForOrigin:currentSelection];
         if (theTile) {
             NSData *tileData = [NSKeyedArchiver archivedDataWithRootObject:theTile];
             if (tileData)
                 [gpBoard setData:tileData forPasteboardType:ColorTileUTI];
         }
     }
      
     - (void)cut:(id)sender {
         [self copy:sender];
         ColorTile *theTile = [self colorTileForOrigin:currentSelection];
    
         if (theTile) {
             CGPoint tilePoint = theTile.tileOrigin;
             [tiles removeObject:theTile];
             CGRect tileRect = [self rectFromOrigin:tilePoint inset:TILE_INSET];
             [self setNeedsDisplayInRect:tileRect];
         }
     }
    

粘貼選中內(nèi)容

當(dāng)用戶點(diǎn)擊粘貼命令是,系統(tǒng)調(diào)用了響應(yīng)者的paste:方法蜕猫。同樣寂曹,該消息也會從第一響應(yīng)者開始沿響應(yīng)鏈傳送。

實(shí)現(xiàn)paste:方法時(shí)回右,你從剪切板中以一種能夠支持的表示讀入對象隆圆。然后添加被粘貼對象到你的應(yīng)用中的數(shù)據(jù)中,并在頁面中展示翔烁。該操作包含以下步驟:

  1. 獲取一個(gè)剪切板對象

  2. 驗(yàn)證剪切板的第一個(gè)對象包含應(yīng)用能支持的表示渺氧。通過調(diào)用 containsPasteboardTypes:或者pasteboardTypes方法獲取所有表示。注意蹬屹,你需要在canPerformAction:withSender:中執(zhí)行該步驟侣背。

  3. 如果剪切板的第一個(gè)條目包含該應(yīng)用能夠處理的數(shù)據(jù),調(diào)用下面方法中的一個(gè)來讀數(shù)據(jù):

    • dataForPasteboardType: 如果要讀的數(shù)據(jù)包含在NSData對象中慨默,調(diào)用此方法贩耐。
    • valueForPasteboardType: 如果要讀的數(shù)據(jù)為屬性列表數(shù)據(jù),調(diào)用此方法业筏。
  4. 將該對象添加到應(yīng)用的數(shù)據(jù)中憔杨。

  5. 展示該數(shù)據(jù)。

     - (void)paste:(id)sender {
         UIPasteboard *gpBoard = [UIPasteboard generalPasteboard];
         NSArray *pbType = [NSArray arrayWithObject:ColorTileUTI];
         ColorTile *theTile = [self colorTileForOrigin:currentSelection];
         if (theTile == nil && [gpBoard containsPasteboardTypes:pbType]) {
             NSData *tileData = [gpBoard dataForPasteboardType:ColorTileUTI];
             ColorTile *theTile = (ColorTile *)[NSKeyedUnarchiver unarchiveObjectWithData:tileData];
             if (theTile) {
                 theTile.tileOrigin = self.currentSelection;
                 [tiles addObject:theTile];
                 CGRect tileRect = [self rectFromOrigin:currentSelection inset:TILE_INSET];
                 [self setNeedsDisplayInRect:tileRect];
             }
         }
     }
    

結(jié)束操作

當(dāng)cut:, copy: 或者 paste:方法返回時(shí)蒜胖,編輯菜單自動隱藏消别。你可以讓他保持可見抛蚤,具體可查看Dismissing the Edit Menu

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市寻狂,隨后出現(xiàn)的幾起案子岁经,更是在濱河造成了極大的恐慌,老刑警劉巖蛇券,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缀壤,死亡現(xiàn)場離奇詭異,居然都是意外死亡纠亚,警方通過查閱死者的電腦和手機(jī)塘慕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒂胞,“玉大人图呢,你說我怎么就攤上這事∑妫” “怎么了蛤织?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鸿染。 經(jīng)常有香客問我指蚜,道長,這世上最難降的妖魔是什么涨椒? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任摊鸡,我火速辦了婚禮,結(jié)果婚禮上丢烘,老公的妹妹穿的比我還像新娘柱宦。我一直安慰自己,他們只是感情好播瞳,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布掸刊。 她就那樣靜靜地躺著,像睡著了一般赢乓。 火紅的嫁衣襯著肌膚如雪忧侧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天牌芋,我揣著相機(jī)與錄音蚓炬,去河邊找鬼。 笑死躺屁,一個(gè)胖子當(dāng)著我的面吹牛肯夏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼驯击,長吁一口氣:“原來是場噩夢啊……” “哼烁兰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起徊都,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤沪斟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后暇矫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體主之,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年李根,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了槽奕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡朱巨,死狀恐怖史翘,靈堂內(nèi)的尸體忽然破棺而出枉长,到底是詐尸還是另有隱情冀续,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布必峰,位于F島的核電站洪唐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吼蚁。R本人自食惡果不足惜凭需,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肝匆。 院中可真熱鬧粒蜈,春花似錦、人聲如沸旗国。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽能曾。三九已至度硝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間寿冕,已是汗流浹背蕊程。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留驼唱,地道東北人藻茂。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親辨赐。 傳聞我的和親對象是個(gè)殘疾皇子岗钩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

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

  • 用戶可以在一個(gè)app中復(fù)制文本森枪、圖片视搏、或者其他數(shù)據(jù),并粘貼該數(shù)據(jù)到該app的其他位置县袱,或不同的app中浑娜。例如,你可...
    raingu24閱讀 4,166評論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理式散,服務(wù)發(fā)現(xiàn)筋遭,斷路器,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 展示并操作編輯菜單 編輯菜單是一個(gè)上下文菜單暴拄,它展示并提供了一些命令漓滔,這些命令能夠操作選中內(nèi)容,例如一個(gè)文本頁面中...
    卓小土閱讀 180評論 0 0
  • 翻譯自“Collection View Programming Guide for iOS” 0 關(guān)于iOS集合視...
    lakerszhy閱讀 3,861評論 1 22
  • 內(nèi)容來自于 iOS文檔中 About Text Handling in iOS 部分 ios平臺提供了顯示及編輯文...
    縱橫而樂閱讀 6,768評論 2 21