TextKit框架详细解析 (十二) —— 文本编程指南之展示和管理编辑菜单(八)

版本记录

版本号 时间
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框架详细解析 (九) —— 文本编程指南之管理键盘(五)
10. TextKit框架详细解析 (十) —— 文本编程指南之复制、剪切和粘贴操作(六)
11. TextKit框架详细解析 (十一) —— 文本编程指南之输入数据的自定义视图(七)

Displaying and Managing the Edit Menu - 展示和管理编辑菜单

编辑菜单是一个上下文菜单,显示该菜单以提供可以对选择执行的命令,例如文本视图中的单词或图像。 编辑菜单是复制,剪切和粘贴操作的组成部分,它可以显示(可能)命令Copy, Cut, Paste, Select, and Select All。 但是,您可以将自定义菜单项添加到编辑菜单,以对选择执行其他类型的操作。


Managing the Selection and the Edit Menu - 管理选择和编辑菜单

要在视图中复制或剪切某些内容,或对其执行任何其他操作,必须选择“某些内容”。它可以是一系列文本,图像,URL,颜色或任何其他数据表示,包括自定义对象。您必须自己管理该视图中的对象选择。如果用户通过进行特定的触摸手势(例如,双击)选择视图中的对象,则必须处理该事件,在内部记录选择(并取消选择任何先前的选择),并且可能在视觉上指示新的选择。如果用户可以在视图中选择多个对象进行复制剪切粘贴操作,则必须实现该多选行为。

注意:Event Handling Guide for iOS中讨论了处理触摸事件的技术,包括手势识别器的使用。

当您的应用确定用户已请求编辑菜单(可能是进行选择的操作)时,您应完成以下步骤以显示菜单:

  • 1)调用UIMenuControllersharedMenuController类方法来获取全局菜单控制器实例。
  • 2)计算选择的边界,并使用生成的矩形调用setTargetRect:inView:方法。编辑菜单显示在此矩形的上方或下方,具体取决于选择与屏幕顶部或底部的距离。
  • 3)调用setMenuVisible:animated:方法(两个参数均为YES),以对选择上方或下方的编辑菜单的显示进行动画处理。

Listing 7-1说明了如何在touchesEnded:withEvent:方法的实现中显示编辑菜单,以处理复制,剪切和粘贴操作。 (请注意,该示例省略了处理选择的代码部分。)此代码段还显示自定义视图向自身发送一个becomeFirstResponder消息,以确保它是后续复制,剪切和粘贴操作的第一个响应者。

// Listing 7-1  Displaying the edit menu

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *theTouch = [touches anyObject];
 
    if ([theTouch tapCount] == 2  && [self becomeFirstResponder]) {
 
        // selection management code goes here...
 
        // bring up edit menu.
        UIMenuController *theMenu = [UIMenuController sharedMenuController];
        CGRect selectionRect = CGRectMake (currentSelection.x, currentSelection.y, SIDE, SIDE);
        [theMenu setTargetRect:selectionRect inView:self];
        [theMenu setMenuVisible:YES animated:YES];
 
    }
}

菜单最初包括第一响应者具有相应的UIResponderStandardEditActions方法实现的所有命令(copy:,paste:等等)。但是,在显示菜单之前,系统会向第一个响应者发送canPerformAction:withSender:消息,在许多情况下,该消息是自定义视图。在其实现此方法时,响应者评估命令(由第一个参数中的选择器指示)是否适用于当前上下文。例如,如果selector是paste:并且视图可以处理的类型的粘贴板中没有数据,则响应者应返回NO以禁止粘贴命令。如果第一个响应者没有实现canPerformAction:withSender:方法,或者没有处理给定的命令,则消息会在响应者链中向上传播。

Listing 7-2显示了canPerformAction:withSender:方法的实现,该方法查找与cut:,copy:paste:selectors匹配的消息;它根据当前选择上下文启用或禁用“复制”,“剪切”和“粘贴”菜单命令,对于粘贴,启用或禁用粘贴板的内容。

// Listing 7-2  Conditionally enabling menu commands

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    BOOL retValue = NO;
    ColorTile *theTile = [self colorTileForOrigin:currentSelection];
 
    if (action == @selector(paste:) )
        retValue = (theTile == nil) &&
             [[UIPasteboard generalPasteboard] containsPasteboardTypes:
             [NSArray arrayWithObject:ColorTileUTI]];
    else if ( action == @selector(cut:) || action == @selector(copy:) )
        retValue = (theTile != nil);
    else
        retValue = [super canPerformAction:action withSender:sender];
    return retValue;
}

请注意,此方法中的最后一个else子句调用超类实现,以便为任何超类提供处理子类选择忽略的命令的机会。

请注意,菜单命令在作用时可以更改其他菜单命令的上下文。 例如,如果用户选择视图中的所有对象,则复制和剪切命令应包含在菜单中。 在这种情况下,响应者可以在菜单仍然可见的情况下,在菜单控制器上调用update;这导致canPerformAction:withSender:在第一个响应者上重新调用。


Adding Custom Items to the Edit Menu - 将自定义项添加到编辑菜单

您可以将自定义项添加到编辑菜单。 当用户点击此项时,会发出一个命令,以特定于应用程序的方式影响当前目标。 UIKit框架通过target-action mechanism实现了这一点。 项目的点击导致将动作消息发送到响应者链中可以处理该消息的第一个对象。 图7-1显示了自定义菜单项的示例(“Change Color”)。

Figure 7-1 An edit menu with a custom menu item

UIMenuItem类的实例表示自定义菜单项。 UIMenuItem对象有两个属性,title and an action selector,您可以随时更改它们。 要实现自定义菜单项,必须使用这些属性初始化UIMenuItem实例,将实例添加到菜单控制器的自定义菜单项数组中,然后实现操作方法以在相应的响应程序子类中处理该命令。

实现自定义菜单项的其他方面对于使用单例UIMenuController对象的所有代码都是通用的。 在自定义或重写视图中,将视图设置为第一个响应者,获取共享菜单控制器,设置目标矩形,然后通过调用setMenuVisible:animated:显示编辑菜单。 Listing 7-3中的简单示例添加了一个自定义菜单项,用于在红色和黑色之间更改自定义视图的颜色。

// Listing 7-3  Implementing a Change Color menu item

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *theTouch = [touches anyObject];
    if ([theTouch tapCount] == 2) {
        [self becomeFirstResponder];
        UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Change Color" action:@selector(changeColor:)];
        UIMenuController *menuCont = [UIMenuController sharedMenuController];
        [menuCont setTargetRect:self.frame inView:self.superview];
        menuCont.arrowDirection = UIMenuControllerArrowLeft;
        menuCont.menuItems = [NSArray arrayWithObject:menuItem];
        [menuCont setMenuVisible:YES animated:YES];
    }
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {}
 
- (BOOL)canBecomeFirstResponder { return YES; }
 
- (void)changeColor:(id)sender {
    if ([self.viewColor isEqual:[UIColor blackColor]]) {
        self.viewColor = [UIColor redColor];
    } else {
        self.viewColor = [UIColor blackColor];
    }
    [self setNeedsDisplay];
}

注意:UIMenuControllerarrowDirection属性(如Listing 7-3所示)允许您指定箭头附加到编辑菜单指向其目标矩形的方向。


Dismissing the Edit Menu - 移除编辑菜单

当您执行系统或自定义命令时,编辑菜单会自动隐藏。 您可以使用以下代码行保持菜单可见:

[UIMenuController sharedMenuController] .menuVisible = YES;

系统可以随时隐藏编辑菜单。 例如,当显示alert弹窗或用户点击屏幕的另一个区域时,它会隐藏菜单。 如果您的状态或显示取决于编辑菜单是否可见,您应该监听名为UIMenuControllerWillHideMenuNotification的通知并采取适当的操作。

后记

本篇主要讲述了展示和管理编辑菜单,感兴趣的给个赞或者关注~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容