先上图,这是最终功能实现效果图
其实很简单,首先创建一个继承了UILabel的MLLongPressLabel,然后给UIlabel添加一个长按手势就可以了.先贴出具体代码
#import <UIKit/UIKit.h>
@interface MLLongPressCopyLabel : UILabel
@end
#import "MLLongPressCopyLabel.h"
@implementation MLLongPressCopyLabel
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
//让label能够响应用户的交互
self.userInteractionEnabled = YES;
//给label添加手势
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] init];
//设置长按最少需要2s
longPressGesture.minimumPressDuration = 2;
//添加长按响应事件
[longPressGesture addTarget:self action:@selector(longPressAction:)];
//添加手势
[self addGestureRecognizer:longPressGesture];
}
return self;
}
//长按手势事件
- (void)longPressAction:(UILongPressGestureRecognizer *)longPressGes
{
//让label成为第一响应者
[self becomeFirstResponder];
//长按label时展示出复制选项(还可以定义剪贴,粘贴)
//创建UIMenuController
UIMenuItem *copyItem = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyAction)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:copyItem]];
//设置frame和添加到的视图
[[UIMenuController sharedMenuController] setTargetRect:self.frame inView:self.superview];
//设置弹窗可见
[[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
}
//copy按钮点击事件
- (void)copyAction
{
//将label上的字符串保存到 UIPasteboard 上
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = self.text;
}
#pragma mark -- UIResponder
//本来UIlabel是不能成为响应者的,在这里重写方法
- (BOOL)canBecomeFirstResponder
{
return YES;
}
//控制响应的方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return action == @selector(copyAction);
}
@end
注意点:
1.一定要让UILabel成为第一响应者
[self becomeFirstResponder]
2.要让UILabel成为第一响应者,必须重写继承自UIResponder的方法
//本来UIlabel是不能成为响应者的,在这里重写方法
- (BOOL)canBecomeFirstResponder
{
return YES;
}
//控制响应的方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return action == @selector(copyAction);
}
如果缺少任意一步,那么复制的小菜单都不能弹出来.
我于是产生了一个疑问,那就是为什么一定要成为第一响应者才能弹出菜单呢,我以前也给UILabel添加过手势,实现了点击跳转的功能.难道这个弹窗有什么特别吗?通过查资料,我得到结论,那就是:
必须要得通过第一响应者,来告诉MenuController它内部应该显示什么内容
因此,我们必须要设置UILabel成为第一响应者才行
参考文章:
简单实现UIlabel可复制功能
解析iOS开发中的FirstResponder第一响应对象
iOS --苹果自带的UIMenuController功能扩展