UITextView自定义菜单选项(刚刚爬出坑来)

前言

今天有一个小需求,就是在UITextView里面长按显示菜单那里面去自定义菜单,不用系统默认显示的。本来一个很好实现的小功能,网上一查有很多。但是我按照人家给的思路去做了之后发现,新增的自定义菜单是有了,但是系统的还是没有去掉。结果傻眼了。然后摸索了一阵子,突发奇想的就换了个思路搞好了。现在想一下,确实自己很二了。

正文

API分析

显示菜单说白了就是一个VC,用于显示咱们这种长按特殊需求的小界面。
进入UIMenuController的API你会发现这是一个单例类,至于怎么发现的,看下构造方法就知道了:

+ (UIMenuController *)sharedMenuController;

就这么一个构造方法,而且你想一下,菜单显示这个确实是单例实现的最佳范例呀,不可能同时在一个Windows出现。
UIMenuController里面的内容很少,基本都能看懂。不懂得百度一下也就知道,我也不多说了。
UIMenuController只是一个外表显示,一个VC构建了一个空的界面,里面有什么就需要你自己去填充了,当然不可能阿猫阿狗都能填充,这时候就需要UIMenuItem了。
UIMenuItem的API就只有一个方法

NS_CLASS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED @interface UIMenuItem : NSObject 

- (instancetype)initWithTitle:(NSString *)title action:(SEL)action NS_DESIGNATED_INITIALIZER;

@property(nonatomic,copy) NSString *title;
@property(nonatomic)      SEL       action;

@end

熟悉不,和手势的创建很像吧(本来想说和UITabBarItem很像,但是仔细一想形式很像,作用很像,但是创建方法他们两个有些不合适)。
这个方法就是给一个标题一个事件,没了。灰常简单有木有。

第一次实践进行

然后我就按照我搜索的网上的各位人士给的方法去干:

- (void)viewDidLoad {
    [super viewDidLoad];
    //设置输入视图
    self.textView = [[UITextView alloc]initWithFrame:CGRectMake(10, 20, CGRectGetWidth(self.view.frame) - 20, CGRectGetHeight(self.view.frame) - 40)];
    self.textView.layer.borderWidth = 2;
    self.textView.layer.borderColor = [UIColor redColor].CGColor;
    self.textView.delegate = self;
    [self.view addSubview:self.textView];
    
    //设置菜单
    UIMenuItem *menuItem = [[UIMenuItem alloc]initWithTitle:@"响应菜单" action:@selector(selfMenu:)];
    UIMenuController *menuController = [UIMenuController sharedMenuController];
    [menuController setMenuItems:[NSArray arrayWithObject:menuItem]];
}

然后,使用一个UIResponder类特意声明去处理的一个方法,响应者类可以实现这个方法,以根据当前的上下文显示或移除编辑菜单上的命令。(摘抄过来的,我感觉说的挺容易理解的)。

//隐藏系统菜单的方法
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    //允许显示
    if (action == @selector(selfMenu:)) {
        return YES;
    }
    //其他不允许显示
    return NO;
}

理论上,码上这些,应该是可以隐藏系统的菜单显示自定义的菜单了,然后我去运行:

运行结果

这是怎么了?fuck the world。不是应该是只显示自定义的菜单了吗,系统的不是应该在UIResponder那个方法里面隐藏了吗?刚开始我有点怀疑我搜到的答案不对,结果又搜了好几个都是这样。然后自己鼓捣一会,结果还是好的,世界总是美好的。

正确做法

继承UITextView,把实现自定义菜单代码放在里面

#import "MyTextView.h"

@implementation MyTextView

- (instancetype)initWithFrame:(CGRect)frame{

    self = [super initWithFrame:frame];
    if (self) {
        UIMenuItem *menuItem = [[UIMenuItem alloc]initWithTitle:@"响应事件" action:@selector(selfMenu:)];
        UIMenuController *menuController = [UIMenuController sharedMenuController];
        [
         menuController
         setMenuItems:[NSArray arrayWithObject:menuItem]];
        [menuController setMenuVisible:NO];
    }
    return self;
}

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(selfMenu:)) {
        return YES;
    }
    return NO;
}

//自定义的事件
- (void)selfMenu:(id)sender{
    
    
}
@end

然后,使用自定义的UITextView

- (void)viewDidLoad {
    [super viewDidLoad];
    //设置输入视图
    self.textView = [[MyTextView alloc]initWithFrame:CGRectMake(10, 20, CGRectGetWidth(self.view.frame) - 20, CGRectGetHeight(self.view.frame) - 40)];
    self.textView.layer.borderWidth = 2;
    self.textView.layer.borderColor = [UIColor redColor].CGColor;
    self.textView.delegate = self;
    [self.view addSubview:self.textView];
    
}

运行:

运行结果

正常运行有木有,我感觉出问题的原因应该是和那个UIResponder的方法有问题,因为我在界面上进行的一切手势事件他都会拦截的。所以直接在UITextView可能造成问题,只是个人猜测,大神知道了请告诉小弟呀。

结语

这也是一个小坑吧。估计会有人像我一样遇到,所以写在这,如果在遇到这个问题的时候看到我这篇小文章,希望对你有帮助。

备注:本文是自己写的一些理解,可能有不对之处。如有请您能指出来,我马上去校队修改。

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

推荐阅读更多精彩内容