点击控件弹出复制粘贴剪切选择等(UIMenuController)
默认情况下,有以下控件已经支持UIMenuController
UITextField
UITextView
UIWedView
以UITable为例,说明点击后弹出复制剪切粘贴等为例
使用的整体思路:(系统自带的文字)
1、新建一个UILabel的类,如果想以后storyboard和Xib都可以用,就可以调用awakeFromNib和initWithFrame方法,同时进行初始化操作
2、使UILabel成为第一响应者作用:
提供两种方法canBecomeFirstResponder和canPerformAction(两种必写)
同时告诉UIMenuController支持哪些操作,这些操作如何处理。
3、创建UIMenuController对象,设置两个条件
首先:设置弹出的对象显示的范围
然后:让对象能够显现出来,且动画方式出现
4、UIMenuController对象的各类方法操作的实现(copy,paste,cut等)
1 #import "ZWLabel.h" 2 3 @implementation ZWLabel 4 5 - (void)awakeFromNib 6 { 7 [self setup]; 8 } 9 - (instancetype)initWithFrame:(CGRect)frame 10 { 11 if (self = [super initWithFrame:frame]) { 12 [self setup]; 13 } 14 return self; 15 } 16 /** 17 * 初始化操作 18 */ 19 - (void)setup 20 { 21 self.userInteractionEnabled = YES; 22 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelClick)]; 23 [self addGestureRecognizer:tap]; 24 } 25 /** 26 * 点击后操作 27 */ 28 - (void)labelClick 29 { 30 //使之成为第一响应者,成为之后会提供两种方法becomeFirstResponder和canPerformAction 31 //同时告诉UIMenuController支持哪些操作,这些操作如何处理 32 [self becomeFirstResponder]; 33 34 //创建menu控制器 35 UIMenuController *menu = [UIMenuController sharedMenuController]; 36 //弹出的menu显示在哪个区域(两种方式) 37 // [menu setTargetRect:self.frame inView:self.superview]; 38 [menu setTargetRect:self.bounds inView:self]; 39 //使menu可见 40 [menu setMenuVisible:YES animated:YES]; 41 } 42 43 /** 44 * 是label能成为第一响应者 45 */ 46 - (BOOL)canBecomeFirstResponder 47 { 48 return YES; 49 } 50 51 /** 52 * label能执行哪些操作(比如copy,paste) 53 */ 54 - (BOOL)canPerformAction:(SEL)action withSender:(id)sender 55 { 56 NSLog(@"%@",NSStringFromSelector(action));//此处可以打印出支持哪些操作(比如copy,cut,paste等,详情见最底部的打印结果) 57 if (action == @selector(copy:) || action == @selector(cut:) || action == @selector(paste:)) return YES; 58 return NO; 59 } 60 61 - (void)copy:(UIMenuController *)menu 62 { 63 //将自己的文字复制到粘贴板 64 UIPasteboard *board = [UIPasteboard generalPasteboard]; 65 board.string = self.text; 66 } 67 - (void)cut:(UIMenuController *)menu 68 { 69 //将自己的文字复制到粘贴板 70 [self copy:menu]; 71 //清空文字 72 self.text = nil; 73 } 74 - (void)paste:(UIMenuController *)menu 75 { 76 UIPasteboard *board = [UIPasteboard generalPasteboard]; 77 self.text = board.string; 78 }
使用自定义文字
整体都需要移动到viewController中,否则虽然都在UILabel中,能正确运行,但是会提示一堆警告。
即不用重新新建一个继承自UILabel的类,只需要添加了一个UIMenuItem对象,去除掉canPerformAction以及相关的方法即可,代码如下:
注意:需要在label中勾上userInteractionEnabled
1 #import "ViewController.h" 2 @interface ViewController () 3 @property (weak, nonatomic) IBOutlet UILabel *textLabel; 4 5 @end 6 7 @implementation ViewController 8 9 - (void)viewDidLoad { 10 [super viewDidLoad]; 11 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelClick)]; 12 [self.textLabel addGestureRecognizer:tap]; 13 } 14 15 /** 16 * 点击后操作 17 */ 18 - (void)labelClick 19 { 20 //使之成为第一响应者,成为之后会提供两种方法becomeFirstResponder和canPerformAction 21 //同时告诉UIMenuController支持哪些操作,这些操作如何处理 22 [self.textLabel becomeFirstResponder]; 23 24 //创建menu控制器 25 UIMenuController *menu = [UIMenuController sharedMenuController]; 26 27 //弹出的menu显示在哪个区域 28 // [menu setTargetRect:self.frame inView:self.superview]; 29 [menu setTargetRect:self.textLabel.bounds inView:self.textLabel]; 30 //使menu可见 31 [menu setMenuVisible:YES animated:YES]; 32 33 //自定义menuItem 34 UIMenuItem *ding = [[UIMenuItem alloc] initWithTitle:@"顶" action:@selector(ding:)]; 35 UIMenuItem *replay = [[UIMenuItem alloc] initWithTitle:@"回复" action:@selector(replay:)]; 36 UIMenuItem *report = [[UIMenuItem alloc] initWithTitle:@"举报" action:@selector(report:)]; 37 menu.menuItems = @[ding,replay,report]; 38 } 39 40 - (void)ding:(UIMenuController *)menu 41 { 42 NSLog(@"%s %@",__func__,menu); 43 } 44 - (void)replay:(UIMenuController *)menu 45 { 46 NSLog(@"%s %@",__func__,menu); 47 } 48 - (void)report:(UIMenuController *)menu 49 { 50 NSLog(@"%s %@",__func__,menu); 51 } 52 - (BOOL)canBecomeFirstResponder 53 { 54 return YES; 55 }
注: 碰到一个比较奇怪的问题,当使用自定义类型的时候,如果加一个条件:当再次点击label的时候,弹出的menu消失,加入判断
1 if (menu.isMenuVisible) { 2 [menu setMenuVisible:NO animated:YES]; 3 } else {...}
需要把- (void)canBecomeFirstResponder{}这个剪切到ZWLabel中才能实现,否则第二行一直不会执行,menu.isMenuVisible一直是处于无值状态!!
支持的系统自带的各类方法:
1 2016-07-13 22:34:35.099 UIMenuController[16825:1745455] cut: 2 2016-07-13 22:34:35.100 UIMenuController[16825:1745455] copy: 3 2016-07-13 22:34:35.100 UIMenuController[16825:1745455] select: 4 2016-07-13 22:34:35.100 UIMenuController[16825:1745455] selectAll: 5 2016-07-13 22:34:35.100 UIMenuController[16825:1745455] paste: 6 2016-07-13 22:34:35.100 UIMenuController[16825:1745455] delete: 7 2016-07-13 22:34:35.100 UIMenuController[16825:1745455] _promptForReplace: 8 2016-07-13 22:34:35.100 UIMenuController[16825:1745455] _transliterateChinese: 9 2016-07-13 22:34:35.101 UIMenuController[16825:1745455] _showTextStyleOptions: 10 2016-07-13 22:34:35.101 UIMenuController[16825:1745455] _define: 11 2016-07-13 22:34:35.101 UIMenuController[16825:1745455] _addShortcut: 12 2016-07-13 22:34:35.101 UIMenuController[16825:1745455] _accessibilitySpeak: 13 2016-07-13 22:34:35.101 UIMenuController[16825:1745455] _accessibilitySpeakLanguageSelection: 14 2016-07-13 22:34:35.101 UIMenuController[16825:1745455] _accessibilityPauseSpeaking: 15 2016-07-13 22:34:35.102 UIMenuController[16825:1745455] _share: 16 2016-07-13 22:34:35.102 UIMenuController[16825:1745455] makeTextWritingDirectionRightToLeft: 17 2016-07-13 22:34:35.102 UIMenuController[16825:1745455] makeTextWritingDirectionLeftToRight: