iOS:菜单控制器和菜单项:UIMenuController和UIMenuItem
转载自 https://www.cnblogs.com/XYQ-208910/p/4862199.html
菜单控制器和菜单项:弹出自定义的菜单栏窗口
提示:
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个方法,缺一不可:
- becomFirstResponder方法,使view或者viewController的self成为第一响应者,可以在相应文件的任意地方调用实现该方法,不过建议与UIMenuController放在一起。
[self becomeFirstResponder];
- 设置-(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(165, 255, 40, 40)]; //设置圆角 [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(10, 256, 350, 40) 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设置)
点击复制时:
2015-10-08 20:26:08.150 菜单控制器和菜单项[5850:321636] 复制成功
点击粘贴时:
2015-10-08 20:26:10.039 菜单控制器和菜单项[5850:321636] 粘贴成功
点击剪贴时:
2015-10-08 20:26:11.878 菜单控制器和菜单项[5850:321636] 剪贴成功