美文网首页
iOS文本编程指南(六)

iOS文本编程指南(六)

作者: 卓小土 | 来源:发表于2017-02-07 20:52 被阅读0次

复制,剪切,粘贴操作

用户可以复制某个应用中的文本,图片,或者其他数据到另外一个地方,到该应用内或者另一个应用都可以。UIKit Framework在UITextView中实现了复制-剪切-粘贴操作,如果你想要拥有这些行为,你可以使用这些类或者自己实现复制-剪切-粘贴。

下面的内容描述了UIKit的接口,如何使用复制,剪切,粘贴操作。

注:和复制粘贴操作相关的指导,看iOS Human Interface Guidelines.中的“Supporting Copy and Paste”一节

UIKit的复制粘贴操作

UIKit中提供了几个类和一个非正式协议(译者注:非正式协议在较早的版本用分类实现,目前用协议实现,协议中的方法为可选类型)以及一种机制,让你能够实现复制,剪切,粘贴操作。

  • UIPasteboard类提供了剪切板:共享数据的保存的地方。这个类提供了从剪切板按条读写数据的方法。
  • UIMenuController类展示了编辑菜单,出现在选中内容的上方或者下方。编辑菜单默认的命令是复制,剪切,粘贴,选中和全选。你可以在编辑菜单中添加自定义条目。
  • UIResponder类声明了canPerformAction:withSender:方法。响应类可以实现该方法,来让某些编辑条目根据当前选中内容出现或移除。
  • UIResponderStandardEditActions 非正式协议声明了处理复制,剪切,粘贴,选中以及全选命令的接口。当用户点击了一个命令时,响应的方法会被调用。(译者注:UITextView实现了改协议)

剪切板

剪切版是应用内或应用间交换数据的的标准机制。其最常见的用处是复制,剪切,粘贴操作。

  • 当用户选中了数据,并且选择了复制(或剪切)命令,那么被选中的数据就被放入了剪切板
  • 当用户选择了粘贴命令,在剪切板中的数据就被复制到了当前应用中。

在iOS中,剪切板也用来支持查找操作。并且,你可以使用自定义的URL机制代替复制,剪切,粘贴操作,让剪切板在应用间传输数据。具体信息参照Info.plist的设置。

抛开具体操作,剪切板的基本功能是往里写数据和从中读数据。虽然概念简单,但是包含了诸多细节。主要复杂的地方在于数据的表达有多种方式,这种复杂性就导致了也需要考虑性能。下面就会讨论一下这些问题。

命名剪切板

剪切板可能是共有的或是私有的。共有的剪切板被称作系统剪切板,私有的剪切板是应用创建的,因此被称作应用剪切板。剪切板必须拥有一个唯一的名字。UIPasteboard定义了两个系统剪切板,它们的名字和用处如下:

  • UIPasteboardNameGeneral 涉及多种类型数据的剪切,复制和粘贴操作。你可以通过generalPasteboard 类方法获取这个单例。
  • UIPasteboardNameFind 用作查找操作。用户在UISearchBar中输入的字符串会被写入到该剪切板中,因此可以在应用间共享。你可以通过调用 pasteboardWithName:create:类方法,传入UIPasteboardNameFind参数来获取该对象。

通常你都会使用系统剪切板,如果有必要你可以通过调用cpasteboardWithName:create:方法创建你自己的应用剪切板。调用pasteboardWithUniqueName这个方法也可以,一个拥有唯一名字的应用剪切板会被创建出来,名字可以通过剪切板对象的name属性查看。

剪切板的持久化

剪切板能够被持久化。如果剪切板被持久化,可以在之前的应用退出之后或者系统重启之后使用。系统剪切板是持久化的。虽然应用剪切板默认是不持久化的,你可以通过设置persistent属性为YES来使他们变成可持久化的。不持久化的剪切板在应用退出时就没了,持久化的剪切板在应用卸载时被移除掉。

剪切板持有者和条目

最后一次向剪切板中加入数据的对象被视作剪切板持有者。每一条向剪切板中加入的数据被视作剪切板条目。剪切板可以持有一条或多条条目。应用能够加入和跟踪任意数量的条目。例如,比如一个用户选择了文字+图片。他们被复制到剪切板时,文本和图片作为不同的条目。应用读取多个条目,可以选择那些需要支持的(例如,只需要处理文字而不需要处理图片)。

表示与UTI

剪切板操作经常是跨应用的。没有应用可以知道另外一个应用可以处理哪些数据。为了最大化这种共享的能力,剪切板可以对一个剪切板条目进行多种表示。例如,一个富文本编辑器可能对一份拷贝数据提供了HTML,PDF和纯文本的表示。一个剪切板条目包括了应用所能提供的所有表示。

每一个剪切板条目通常使用唯一类型标识(UTI)。(UTI就是一个唯一的字符串,用来标记数据类型。)UTI提供了一个统一的标记数据类型的方式。如果你有一个自定义的数据类型想要支持,你必须为它创建一个唯一的标识。对此,你可以使用逆向域名来确保唯一性,例如,一个自定义的类型表示可以是com.myCompany.myApp.myType。更多有关UTI的内容,查看Uniform Type Identifiers Overview

举个例子,假设一个应用支持富文本和图片的选中。它可能想将富文本的Unicode版本和图片的多种表示都放到剪切板中。每一个条目的每种表示被存储在它自身的数据中,如下图:

通常,为了最大化能够共享数据的可能性,剪切板条目应当包含尽可能多的表示。

一个剪切板的读者必须找到最合适的数据类型。典型地,这意味着选择能够支持的最复杂类型。例如,对于一份拷贝的文本数据,文本编辑器应该提供HTML和普通文本的表示。一个能够支持富文本的应用应该使用HTML的表示,而仅能支持普通文本的应用就使用普通文本的版本。

改变数

改变数是剪切板的变量,每次当剪切板的内容发生变化时,它就增加。具体指的是剪切板条目加入、修改或者删除时。通过检查改变数,应用能够检查当前剪切板中的数据是否跟上次获取到的一致。每次改变数增加时,剪切板会给观察者发送通知。

第一步:识别选中并展示编辑菜单

如果你想使用复制,剪切或者粘贴之类的东西,你首先需要选中(一个粘贴操作通常在一个空选中上操作,例如一个光标)。在选中一个条目之后,你应该展示展示编辑菜单。编辑菜单是一个系统菜单,它可能包含以下命令:拷贝,剪切,粘贴,选中和全选。编辑菜单指向被选中内容。当用户点击一个菜单项时,协议UIResponderStandardEditActions中的方法(诸如cut: paste:等方法)就会被调用。

获取更多有关选中以及菜单的展示管理的内容,查看Managing the Selection and the Edit Menu

复制和剪切

当用户点击复制后者剪切命令式,系统会调用相应对象的copy:或者cut:方法。通常是第一响应者实现了这些方法,如果第一响应者没有实现这些方法,消息会沿着响应链传递。非正式协议UIResponderStandardEditActions中定义了这些方法。

注意:任何类可实现UIResponderStandardEditActions中的方法,但是最好是继承UIResponder,并在响应链中的类。

实现copy:或者cut:方法时,你应该向剪切板中写入选中数据的尽可能多的表达。这些操作包括以下步骤(假设只有一个剪切板条目):

  1. 从选中对象中获取数据。二进制数据一定要包在NSData对象中。如果要写入其他类型的数据,那么必须是属性列表对象——也就是说,是如下类型的对象:NSString, NSArray, NSDictionary, NSDate, NSNumber, 或者 NSURL。更多内容,查看Property List Programming Guide

  2. 如果可以,产生一个或更多该对象或数据的表达。例如,如果之前选中了一个UIImage对象,你可以使用UIImageJPEGRepresentation和UIImagePNGRepresentation函数来将该图片转换成不同的表示。

  3. 获取剪切板对象。通常获取通用剪切板,调用 generalPasteboard类方法。

  4. 对于写入剪切板的条目的每一种表示设置一个UTI。

  5. 写入数据到剪切板的第一个位置,对于不同的数据类型:

    • 如果是数据对象,发送setData:forPasteboardType: 消息到剪切板对象
    • 如果是属性列表对象,发送setValue:forPasteboardType: 消息到剪切板。
  6. 如果命令是剪切,从应用的数据中移除选中的对象并更新你的页面。

     - (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];
         }
     }
    

粘贴选中内容

当用户点击粘贴命令是,系统调用了响应者的paste:方法。同样,该消息也会从第一响应者开始沿响应链传送。

实现paste:方法时,你从剪切板中以一种能够支持的表示读入对象。然后添加被粘贴对象到你的应用中的数据中,并在页面中展示。该操作包含以下步骤:

  1. 获取一个剪切板对象

  2. 验证剪切板的第一个对象包含应用能支持的表示。通过调用 containsPasteboardTypes:或者pasteboardTypes方法获取所有表示。注意,你需要在canPerformAction:withSender:中执行该步骤。

  3. 如果剪切板的第一个条目包含该应用能够处理的数据,调用下面方法中的一个来读数据:

    • dataForPasteboardType: 如果要读的数据包含在NSData对象中,调用此方法。
    • valueForPasteboardType: 如果要读的数据为属性列表数据,调用此方法。
  4. 将该对象添加到应用的数据中。

  5. 展示该数据。

     - (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];
             }
         }
     }
    

结束操作

当cut:, copy: 或者 paste:方法返回时,编辑菜单自动隐藏。你可以让他保持可见,具体可查看Dismissing the Edit Menu

相关文章

  • iOS文本编程指南(六)

    复制,剪切,粘贴操作 用户可以复制某个应用中的文本,图片,或者其他数据到另外一个地方,到该应用内或者另一个应用都可...

  • iOS VoiceOver编程指南

    iOS VoiceOver编程指南 iOS VoiceOver编程指南

  • iOS文本编程指南(五)

    管理键盘 当用户点击text field,text view 或者web页上的输入部分的时候,系统就会弹出键盘。你...

  • iOS文本编程指南(七)

    自定义数据输入控件 UIKIt允许应用使用自定义控件代替系统键盘。也可以在系统键盘或自定义输入控件之上放置附件页。...

  • iOS文本编程指南(三)

    印刷术语 本节定义文本系统中一些重要的印刷术语。其中许多相应的概念都反映在系统接口中。 本节中的概念在使用Text...

  • iOS文本编程指南(四)

    管理Text Field与Text View text field与text view有两个主要功能:展示文本并开...

  • iOS文本编程指南(一)

    iOS中的文本处理 iOS平台给你提供了多种展示文本以及让用户编辑文本的方式。同时也能够展示格式化的内容及网页内容...

  • iOS文本编程指南(二)

    iOS展示文本内容 iOS的文本系统功能强大且简单易用。UIKit框架包含一组高级类来管理文本的展示和输入。同时它...

  • iOS文本编程指南(八)

    展示并操作编辑菜单 编辑菜单是一个上下文菜单,它展示并提供了一些命令,这些命令能够操作选中内容,例如一个文本页面中...

  • iOS文本编程指南(九)

    使用Text Kit绘制并管理文本 UIKit框架包含几个类,他们的目的是展示应用界面的文本——UITextVie...

网友评论

      本文标题:iOS文本编程指南(六)

      本文链接:https://www.haomeiwen.com/subject/ygvmittx.html