菜单控制器和菜单项:弹出自定义的菜单栏窗口

提示:

1. Menu所处的View必须实现 – (BOOL)canBecomeFirstResponder, 且返回YES
2. Menu所处的View必须实现 – (BOOL)canPerformAction:withSender, 并根据需求返回YES或NO
3. 必须使Menu所处的View或viewController的self成为First Responder (becomeFirstResponder)
4. 定位Menu (- setTargetRect:inView:)
5. 展示Menu (- setMenuVisible:animated:)

菜单上的箭头指向风格枚举:

typedef NS_ENUM(NSInteger, UIMenuControllerArrowDirection) {

UIMenuControllerArrowDefault,

UIMenuControllerArrowUp,

UIMenuControllerArrowDown,

UIMenuControllerArrowLeft,

UIMenuControllerArrowRight,

};

菜单控制器类:

@interface UIMenuController : NSObject

※默认是UIMenuControllerArrowDefault风格

@property(nonatomic) UIMenuControllerArrowDirection arrowDirection ;

※菜单项数组

@property(nonatomic,copy) NSArray *menuItems ;

※菜单矩形坐标系

@property(nonatomic,readonly) CGRect menuFrame;

※菜单是否可见,默认不可见

@property(nonatomic,getter=isMenuVisible) BOOL menuVisible;     // default is NO

※创建菜单控制器对象的类方法

+ (UIMenuController *)sharedMenuController;

※设置菜单可见性和是否动画

- (void)setMenuVisible:(BOOL)menuVisible animated:(BOOL)animated;

※设置菜单在目标视图中的矩阵坐标

- (void)setTargetRect:(CGRect)targetRect inView:(UIView *)targetView;

※更新

- (void)update;

菜单的一些通知:

※将要显示菜单的通知

UIKIT_EXTERN NSString *const UIMenuControllerWillShowMenuNotification;

※已经显示菜的通知

UIKIT_EXTERN NSString *const UIMenuControllerDidShowMenuNotification;

※将要隐藏菜单的通知

UIKIT_EXTERN NSString *const UIMenuControllerWillHideMenuNotification;

※已经隐藏菜单的通知

UIKIT_EXTERN NSString *const UIMenuControllerDidHideMenuNotification;

※已经改变菜单的通知

UIKIT_EXTERN NSString *const UIMenuControllerMenuFrameDidChangeNotification;

菜单项类:

@interface UIMenuItem : NSObject

※菜单项名

@property(nonatomic,copy) NSString *title;

※菜单项事件

@property(nonatomic)SEL action;

※创建菜单项对象,并添加事件和名字

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

重点:

要想显示弹出菜单,必须实现3个方法,缺一不可:

  1. becomFirstResponder方法,使view或者viewController的self成为第一响应者,可以在相应文件的任意地方调用实现该方法,不过建议与UIMenuController放在一起。

    [self becomeFirstResponder];

  2. 设置-(BOOL) canBecomeFirstResponder的返回值为YES,原因不言而喻。

    -(BOOL) canBecomeFirstResponder{

    return YES;

    }

重载函数-(BOOL) canPerfomAction:(SEL)action withSender:(id)sender,设置要显示的菜单项,返回值为YES。若不进行任何限制,则将显示系统自带的所有菜单项(其他很多的,自己可以 试一下),例如:

-(BOOL) canPerformAction:(SEL)action withSender:(id)sender

{

if (action == @selector(menuItem1Pressed:) || action ==@selector(menuItem2Pressed:) ||

action == @selector(menuItem3Pressed:) || action ==@selector(menuItem4Pressed:))

{

return YES;   //显示菜单项

}

return NO; //隐藏系统默认的菜单项

}

至于相应的菜单响应通过各selector函数来实现,如:

- (IBAction) menuItem1Pressed:(id)sender

{

txtInputLabel.text = @”helleo world″;
     [[UIMenuController sharedMenuController] setMenuVisible:NO animated:YES];

}

如果将系统默认的菜单也显示出来,那么自定义的菜单将作为第二菜单,调用菜单时默认显示的是第一菜单,如果要直接显示第二菜单,可以先设置菜单可见性为NO即可:

[popMenu setMenuVisible:NO animated:YES];

举例如下:

1.创建按钮并设置必要的属性和事件

    //创建按钮并设置相关属性
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(, , , )]; //设置圆角
[btn.layer setMasksToBounds:YES];
btn.layer.cornerRadius = 8.0; //设置标题
[btn setTitle:@"设置" forState:UIControlStateNormal]; //背景颜色
btn.backgroundColor = [UIColor purpleColor]; //添加事件
[btn addTarget:self action:@selector(CreateMenu) forControlEvents:UIControlEventTouchUpInside]; //加入视图中
[self.view addSubview:btn];

2.执行按钮事件,创建菜单

#pragma mark -按钮事件
-(void)CreateMenu
{
//创建菜单控制器对象
UIMenuController *menu = [UIMenuController sharedMenuController]; //创建自定义的三个菜单项
UIMenuItem *CutItem = [[UIMenuItem alloc]initWithTitle:@"剪贴" action:@selector(Cut:)];
UIMenuItem *copyItem = [[UIMenuItem alloc]initWithTitle:@"复制" action:@selector(Copy:)];
UIMenuItem *pasteItem = [[UIMenuItem alloc]initWithTitle:@"粘贴" action:@selector(Paste:)]; //设置菜单控制器箭头风格(朝上)
menu.arrowDirection = UIMenuControllerArrowUp; //设置菜单控制器可见
[menu setMenuVisible:YES]; //给菜单控制器定位
[menu setTargetRect:CGRectMake(, , , ) inView:self.view]; //设置第一响应者
[self becomeFirstResponder]; //设置菜单项数组
NSArray *Items = @[copyItem,pasteItem,CutItem]; //将菜单项加入到菜单控制器中
[menu setMenuItems:Items]; }

3.重写 – (BOOL)canBecomeFirstResponder和– (BOOL)canPerformAction:withSender方法,显示自定义菜单

#pragma mark -实现必须的方法
//设置可以成为第一响应者
-(BOOL)canBecomeFirstResponder
{
return YES;
} //设置要显示的菜单项
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(Cut:) || action == @selector(Copy:) || action == @selector(Paste:))
{
return YES; //显示自定义的菜单项
} return NO; //隐藏系统默认的菜单项
}

4.执行菜单项的方法

#pragma mark -菜单项执行方法
//剪切
-(void)Cut:(UIMenuItem *)sender
{
NSLog(@"剪贴成功");
} //复制
-(void)Copy:(UIMenuItem *)sender
{
NSLog(@"复制成功");
} //粘贴
-(void)Paste:(UIMenuItem *)sender
{
NSLog(@"粘贴成功");
}

5、演示截图如下:(箭头方向可以根据菜单的位置frame设置)

点击复制时:

-- ::08.150 菜单控制器和菜单项[:] 复制成功

点击粘贴时:

-- ::10.039 菜单控制器和菜单项[:] 粘贴成功

点击剪贴时:

-- ::11.878 菜单控制器和菜单项[:] 剪贴成功

iOS:菜单控制器和菜单项:UIMenuController和UIMenuItem的更多相关文章

  1. Delphi在系统菜单中添加菜单项

    unit dy219; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  2. mfc 小程序---在系统菜单中添加菜单项

    1建立一个对话框工程:在dlg类里定义一个菜单指针m_pMenu,在对话框OnInitDialog函数里添加代码: m_pMenu=GetSystemMenu(FALSE);//获取系统菜单的指针 m ...

  3. 为Windows资源管理器右键菜单添加菜单项

    为Windows资源管理器右键菜单添加菜单项 在Windows下命令行用的比较多,经常在资源管理器里翻到某个目录,若想要在此目录下跑命令,只能是打开cmd.exe,然后一路cd才能到达此目录. 每次都 ...

  4. GUI tkinter (Menu)菜单项篇

    """添加顶层菜单:1.我们可以使用Menu类来新建一个菜单,Menu和其他的组件一样,第一个是parent,这里通常可以为窗口2.然后我们可以用add_command方 ...

  5. 在Winform界面菜单中实现动态增加【最近使用的文件】菜单项

    在我们一些和文件处理打交道的系统中,我们往往需要记录下最近使用的文件,这样方便用户快速打开之前浏览或者编辑过的文件,这种在很多软件上很常见,本文主要介绍在Winform界面菜单中实现[最近使用的文件] ...

  6. JCEF 如何修改右键菜单项(JCEF在右键菜单中添加开发者选项-show dev tools)

    需求: 在界面的右键事件中添加一个打开开发者选项的菜单(Show Dev Tools) 所以我们可以看到的是在界面上右键,会有默认的一些菜单项(前进,后退,打印,查看源码),而这些功能并不一定是我们需 ...

  7. Windows下给鼠标右键菜单添加获得完全控制权限的菜单项

    这段时间计算机C分区里多了很多无用的文件,而且不在同一个目录下,搜索出来删除的时候提示没有管理员权限,需要在右键属性里面修改,非常麻烦,于是查询了一下发现可以在文件右键菜单添加一个获取权限的菜单项,这 ...

  8. 在Unity3d编辑器中加入菜单以及菜单项

    在引用UZGUI插件时,u3d编辑器的菜单条发生了变化,新增了菜单和菜单项,于是乎自己也像尝试一下,看了EZGUI的About_EZ_GUI脚本文件后,结果大出我所料,原来SO EASY! using ...

  9. java学习:AWT组件和事件处理的笔记(1)--菜单条,菜单,菜单项

    菜单放在菜单条里,菜单项放在菜单里1.MenuBar    在java.awt包中,负责创建菜单条,即MenuBar的一个实例,便是一个菜单条.    在Frame类中的setMenuBar(Menu ...

随机推荐

  1. web请求响应

    转载自:SanMaoSpace 1.Web开发的定义首先看看微软对Web开发的定义:Web开发是一个指代网页或网站编写过程的广义术语.网页使用 HTML.CSS 和 JavaScript编写.这些页面 ...

  2. 《java并发编程实战》读书笔记7--线程池的使用

    第8章 线程池的使用 8.1 在任务与执行策略之间的隐性耦合 虽然Executor框架为制定和修改执行策略都提供了相当大的灵活性,但并非所有的任务都适用所有的执行策略.有些类型的任务需要明确地指明执行 ...

  3. JAVA 语言类的特性(成员、重载、构造方法、静态成员)

    一.类的私有成员和公有成员 1.私有成员 修饰符private    如果在类的声明前加上修饰符private,则无法从该类的外部访问到该类的内部成员,而只能被该类自身访问和修改,而不嗯那个被其他类, ...

  4. 手动安装gcc 4.8.5

    # 下载gcc wget ftp://ftp.gnu.org/gnu/gcc/gcc-4.8.5/gcc-4.8.5.tar.gz # 解压并进入目录 tar -zxvf gcc-.tar.gz cd ...

  5. git-全家桶

    关于git,网上一片赞美之声,我就不多说啥了,用过才知道,多好. 没有了解过的朋友,可以去大神廖雪峰传送门看看,我就是通过那里学会的基础,再次感谢大神无私的奉献!!! 下面分四个章节: 基础操作(其实 ...

  6. AttributeError: 'ForeignKey' object has no attribute 're' 解决办法

    使用 field_object.rel.model.objects.filter(**db_condition) 报错 forekey中存在rel,为什么不能调用? 通过以下语句观察 print(fi ...

  7. PTA L2-001 紧急救援-最短路(Dijkstra)多条最短路找最优解并输出路径 团体程序设计天梯赛-练习集

    L2-001 紧急救援 (25 分)   作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快 ...

  8. 【转载】文件下载FileDownloader

    原文地址:https://github.com/lingochamp/FileDownloader 特点 简单易用 高并发 灵活 可选择性支持: 独立/非独立进程 自动断点续传 需要注意 当下载的文件 ...

  9. 并发系列1----大白话聊聊Java并发面试问题之volatile到底是什么?【石杉的架构笔记】

  10. HttpClient不同版本超时时间的设置

    引自 https://www.cnblogs.com/hisunhyx/p/5028391.html 3.X是这样的 HttpClient client=new DefaultHttpClient() ...