版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.09.01 |
前言
TextKit
框架是对Core Text
的封装,用简洁的调用方式实现了大部分Core Text
的功能。 TextKit是一个偏上层的开发框架,在iOS7
以上可用,使用它可以方便灵活处理复杂的文本布局,满足开发中对文本布局的各种复杂需求。TextKit实际上是基于CoreText的一个上层框架,其是面向对象的。接下来几篇我们就一起看一下这个框架。感兴趣的看下面几篇文章。
1. TextKit框架详细解析 (一) —— 基本概览和应用场景(一)
2. TextKit框架详细解析 (二) —— 基本概览和应用场景(二)
3. TextKit框架详细解析 (三) —— 一个简单布局示例(一)
4. TextKit框架详细解析 (四) —— 一个简单布局示例(二)
5. TextKit框架详细解析 (五) —— 文本编程指南之简介(一)
6. TextKit框架详细解析 (六) —— 文本编程指南之展示文本内容(二)
7. TextKit框架详细解析 (七) —— 文本编程指南之排版概念(三)
8. TextKit框架详细解析 (八) —— 文本编程指南之管理Text Fields and Text Views(四)
9. TextKit框架详细解析 (九) —— 文本编程指南之管理键盘(五)
Copy, Cut, and Paste Operations - 复制、剪切和粘贴操作
用户可以在一个应用程序中复制文本,图像或其他数据,并将该数据粘贴到同一应用程序或不同应用程序中的其他位置。 例如,您可以在电子邮件中复制个人的地址,并将其粘贴到Contacts
应用中的相应field
中。 UIKit框架在UITextView
和UITextField
类中实现了copy-cut-paste
。 如果您希望在自己的应用程序中使用此行为,则可以使用这些类的对象,也可以自行实现copy-cut-paste
。
以下部分描述了UIKit的编程接口,用于复制,剪切和粘贴操作,并说明如何使用它们。
注意:有关复制和粘贴操作的使用指南,请参阅
iOS Human Interface Guidelines
中的Supporting Copy and Paste
。
Copy-Paste Operations in UIKit - UIKit中的复制粘贴操作
UIKit框架的几个类和非正式协议为您提供了在应用程序中实现复制,剪切和粘贴操作所需的方法和机制:
- UIPasteboard类提供粘贴板:用于在应用程序内或应用程序之间共享数据的保护区域。该类提供了在粘贴板上写入和读取数据项的方法。
- UIMenuController类在选择的上方或下方显示要复制,剪切或粘贴的编辑菜单。编辑菜单的默认命令是(可能)复制,剪切,粘贴,选择和全选。您还可以将自定义菜单项添加到编辑菜单(请参阅 Adding Custom Items to the Edit Menu)。
- UIResponder类声明方法canPerformAction:withSender:。响应者类可以实现此方法,以根据当前上下文显示和删除编辑菜单的命令。
-
UIResponderStandardEditActions
非正式协议声明了用于处理复制,剪切,粘贴,选择和全选命令的接口。当用户点击编辑菜单中的一个命令时,将调用相应的UIResponderStandardEditActions
方法。
Pasteboard Concepts - 粘贴板概念
粘贴板是用于在应用程序内或应用程序之间交换数据的标准化机制。粘贴板最常用的用途是处理复制,剪切和粘贴操作:
- 当用户在应用程序中选择数据并选择“复制(或剪切)”菜单命令时,所选数据将被放置到粘贴板上。
- 当用户选择“粘贴”菜单命令(在相同或不同的应用程序中)时,粘贴板上的数据将从粘贴板复制到当前应用程序。
在iOS中,粘贴板也用于支持查找操作。此外,您可以使用粘贴板使用自定义URL方案而不是复制,剪切和粘贴命令在应用之间传输数据;有关此技术的信息,请参阅Updating Your Info.plist
。
无论操作如何,使用粘贴板对象执行的基本任务都是将数据写入粘贴板并从粘贴板读取数据。虽然这些任务在概念上很简单,但它们掩盖了许多重要的细节。主要的复杂性是可能有多种方式来表示数据,这种复杂性导致了对效率的考虑。以下各节将讨论这些问题和其他问题。
1. Named Pasteboards
粘贴板可以是公共的或私人的。公共粘贴板称为系统粘贴板;私人粘贴板由应用程序创建,因此称为app粘贴板。粘贴板必须具有唯一的名称。 UIPasteboard
定义了两个系统粘贴板,每个粘贴板都有自己的名称和用途:
-
UIPasteboardNameGeneral
用于涉及各种数据类型的剪切,复制和粘贴操作。您可以通过调用generalPasteboard类方法获取表示常规粘贴板的单例对象。 -
UIPasteboardNameFind
用于搜索操作。用户在搜索栏(UISearchBar)
中当前键入的字符串将写入此粘贴板,因此可以在应用程序之间共享。您可以通过调用pasteboardWithName:create:类方法获取表示查找粘贴板的对象,并为该名称传入UIPasteboardNameFind
。
通常您使用系统定义的粘贴板之一,但如果需要,您可以使用pasteboardWithName:create:创建自己的应用粘贴板。如果您调用pasteboardWithUniqueName,UIPasteboard
会为您提供一个具有唯一名称的应用粘贴板。您可以通过其name
属性发现粘贴板的名称。
2. Pasteboard Persistence - 粘贴板持久性
粘贴板可以是持久的。 当粘贴板持久存在时,它将继续存在于应用程序终止之后并且跨系统重新启动。 系统粘贴板是持久的。 虽然默认情况下应用程序粘贴板不是持久性的,但应用程序可以通过将persistent
属性设置为YES
将它们标记为持久性。 不持久的应用程序粘贴板只会持续到拥有(创建)应用程序退出。 在卸载创建它的应用程序时,将删除持久性应用程序粘贴板。
3. Pasteboard Owner and Items - 粘贴板所有者和项目
最后将数据放到粘贴板上的对象称为粘贴板所有者。 放置在粘贴板上的每条数据都被视为粘贴板项目。 粘贴板可以容纳单个或多个项目。 应用可以根据需要放置或检索任意数量的项目。 例如,假设视图中的用户选择包含文本和图像。 通过粘贴板,您可以将文本和图像作为单独的项目复制到粘贴板。 从粘贴板读取多个项目的应用程序可以选择仅采用它支持的项目(例如文本,但不包括图像)。
重要提示:当应用程序将数据写入粘贴板时,即使它只是一个项目,该数据也会替换粘贴板的当前内容。 虽然您可以使用UIPasteboard
的addItems:
方法来追加项目,但是类的write方法不会将项目附加到粘贴板的当前内容。
4. Representations and UTIs
粘贴板操作通常在两个不同的应用程序之间执行。两个应用程序都不需要知道另一个应用程序,包括它可以处理的数据类型。为了最大化共享的可能性,粘贴板可以保存同一粘贴板项目的多个表示。例如,富文本编辑器可能提供复制数据的HTML,PDF和纯文本表示。粘贴板上的项目包括应用程序可以提供的该数据项的所有表示。
粘贴板项的每个表示通常由唯一类型标识符(Unique Type Identifier - UTI)
标识。 (UTI只是一个唯一标识特定数据类型的字符串。)UTI提供了一种识别数据类型的通用方法。如果您希望支持自定义数据类型,则必须为其创建唯一标识符。为此,您可以对表示类型字符串使用反向DNS表示法以确保唯一性;例如,自定义表示类型可以是com.myCompany.myApp.myType
。有关UTI的更多信息,请参阅Uniform Type Identifiers Overview。
例如,假设某个应用程序支持选择富文本和图像。它可能希望在粘贴板上放置文本选择的富文本和Unicode版本以及图像选择的不同表示。每个项目的每个表示都存储有自己的数据,如图5-所示
通常,为了最大化共享的可能性,粘贴板项目应包括尽可能多的不同表示。
粘贴板阅读器必须找到最适合其功能的数据类型(如果有)。 通常,这意味着选择最丰富的类型。 例如,文本编辑器可能提供HTML(富文本)和复制文本数据的纯文本表示。 支持富文本的应用程序应检索HTML表示,并且仅支持纯文本的应用程序应检索纯文本版本。
5. Change Count - 更改数量
更改计数是每个粘贴板变量,每次粘贴板的内容发生更改时都会增加 - 特别是在添加,修改或删除项目时。 通过检查更改计数(通过changeCount
属性),应用程序可以确定粘贴板中的当前数据是否与上次接收的数据相同。 每次更改计数递增时,粘贴板都会向感兴趣的观察者发送通知。
First Steps: Identify the Selection and Display the Edit Menu - 第一步:确定选择并显示编辑菜单
如果要复制,剪切或粘贴某些内容,首先必须选择它。 (粘贴操作通常在空的选择上操作,例如插入符号,指示项目集合中的位置。)选择项目后 - 并在视觉上指示选择 - 您应该显示编辑菜单。 编辑菜单是一个系统菜单,可能包含以下命令:复制,剪切,粘贴,选择和全选。 编辑菜单指向选择。 当用户点击菜单项时,将调用相应的UIResponderStandardEditActions
方法实现(例如cut:
或paste :
)。
有关选择的更多信息以及如何显示和管理编辑菜单,请参阅Managing the Selection and the Edit Menu。
Copying and Cutting the Selection - 复制和剪切选择
当用户点击编辑菜单的“复制”或“剪切”命令时,系统会调用实现它的响应器对象的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。有关此主题的讨论,请参阅Pasteboard Concepts。
-
5)将数据写入每个表示类型的第一个粘贴板项:
- 要编写数据对象,请将setData:forPasteboardType:消息发送到粘贴板对象。
- 要编写属性列表对象,请将setValue:forPasteboardType:消息发送到pasteboard对象。
6)如果命令为Cut
(cut:method)
,则从应用程序的数据模型中删除选择所代表的对象并更新视图。
Listing 5-1
显示了copy:
和cut:
方法的实现。 cut:方法调用copy:方法,然后从视图和数据模型中删除所选对象。请注意,copy:方法存档自定义对象以获取可以传递给setData:forPasteboardType:
中的粘贴板的NSData对象。
// Listing 5-1 Copying and cutting operations
- (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];
}
}
Pasting the Selection - 粘贴选择
当用户点击编辑菜单的粘贴命令时,系统会调用实现它的响应器对象的paste:
方法。通常第一个响应者 - 您的自定义视图 - 实现此方法,但如果第一个响应者没有实现它,则消息以通常的方式传递给响应者。 paste:
方法由UIResponderStandardEditActions
非正式协议声明。
在响应paste:
消息时,您可以使用应用支持的表示形式从粘贴板中读取对象。然后将粘贴的对象添加到应用程序的数据模型,并在用户指示的位置的视图中显示新对象。此操作涉及以下步骤(假设单个粘贴板项目):
1)获取粘贴板对象。在许多情况下,这是一般的粘贴板,您可以通过generalPasteboard类方法获得。
2)通过调用containsPasteboardTypes:方法或pasteboardTypes方法,然后检查返回的类型数组,验证第一个粘贴板项目是否包含应用程序可以处理的表示形式的数据。请注意,您应该已经在canPerformAction:withSender:的实现中执行了此步骤。
-
3)如果粘贴板的第一项包含应用程序可以处理的数据,请调用以下方法之一来读取它:
- dataForPasteboardType:如果要读取的数据封装在NSData对象中。
- valueForPasteboardType:如果要读取的数据封装在属性列表对象中(请参阅Copying and Cutting the Selection)。
4)将对象添加到应用程序的数据模型中。
5)在用户指定的用户界面中显示对象的表示形式。
Listing 5-2
是paste:
方法的一个实现示例。它与组合就剪切和复制方法相反。自定义视图首先查看常规粘贴板是否保存其自定义数据表示形式;如果是这样,它会从粘贴板读取数据,将其添加到应用程序的数据模型中,并标记自身的一部分 - 当前选择 - 用于重绘。
// Listing 5-2 Pasting data to a selection
- (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];
}
}
}
Ending an Operation - 结束操作
当您执行cut:,copy:
或paste:
命令返回时,编辑菜单会自动隐藏。 如果需要,您可以以编程方式使其可见。 有关更多信息,请参阅Dismissing the Edit Menu。
后记
本篇主要讲述了复制、剪切和粘贴操作,感兴趣的给个赞或者关注~~~