一、效果图
二、 会用到的几个类
/**
1、UIPasteboard:可以读写数据
+ (UIPasteboard *)generalPasteboard; ------- 创建
2、UIMenuController:用来显示"复制"、“剪切”等选项的菜单
+ (UIMenuController *)sharedMenuController; ------ 创建
- (void)setMenuVisible:(BOOL)menuVisible animated:(BOOL)animated; ---- 通过动画显示或者隐藏
- (void)setTargetRect:(CGRect)targetRect inView:(UIView *)targetView; ----targetRect menu需要显示的矩形区域 targetView targetRect会以targetView的左上角为坐标原点进行显示
3、UIResponder:指定该UICopyLabel可以响应的方法(这里只需要使用复制)
- (BOOL)canPerformAction:(SEL)action withSender:(nullable id)sender;
*/
三、代码
UICopyLabel.h
#import
@interface UICopyLabel : UILabel
//长按后背景颜色,不赋值默认 Red:235/255.0 green:235/255.0 blue:235/255.0 alpha:1
@property (nonatomic, strong) UIColor *selectedBackgroundColor;
@end
UICopyLabel.m
#import "UICopyLabel.h"
@implementation UICopyLabel
{
UIColor *backgroundColor_;
}
- (void)awakeFromNib {
[super awakeFromNib];
[self becomeFirstResponder];//该句写在此处为解决UICopyLabel与UITextView、UITextField、UIWebView出现在同一个UIView中时的冲突(第一次长按,UIMenuController出现后立刻消失),排除上述情况下使用可以注掉
backgroundColor_ = self.backgroundColor.copy;
[self addLongPressGestureRecognizer];
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self becomeFirstResponder];//该句写在此处为解决UICopyLabel与UITextView、UITextField、UIWebView出现在同一个UIView中时的冲突(第一次长按,UIMenuController出现后立刻消失),排除上述情况下使用可以注掉
backgroundColor_ = self.backgroundColor.copy;
[self addLongPressGestureRecognizer];
}
return self;
}
#pragma mark - 添加长按手势、添加UIMenuController消失的通知
- (void)addLongPressGestureRecognizer {
self.userInteractionEnabled = YES;//打开用户交互 默认为NO
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressHandle:)];
[self addGestureRecognizer:longPress];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuControllerWillHide) name:UIMenuControllerWillHideMenuNotification object:nil];
}
#pragma mark 长按手势处理
- (void)longPressHandle:(UILongPressGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateBegan) {
//UILabel默认是不响应事件的 所以要让它成为第一响应者
[self becomeFirstResponder];
//自定义UIMenuItem
UIMenuItem *copyMenuItem = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyAction:)];
//创建一个UIMenuController对象
UIMenuController *menuVC = [UIMenuController sharedMenuController];
[menuVC setMenuItems:@[copyMenuItem]];
//targetRect menu需要显示的矩形区域
//targetView targetRect会以targetView的左上角为坐标原点进行显示
[menuVC setTargetRect:self.frame inView:self.superview];
//通过动画显示或者隐藏
[menuVC setMenuVisible:YES animated:YES];
self.backgroundColor = self.selectedBackgroundColor?self.selectedBackgroundColor:[UIColor colorWithRed:235/255.0 green:235/255.0 blue:235/255.0 alpha:1];
}
}
#pragma mark 点击“复制”后处理
- (void)copyAction:(id)sender {
[self resignFirstResponder];
//UIPasteboard 的string只能接受 NSString 类型,当Label设置的是attributedText时需要进行转换
UIPasteboard *pastboard = [UIPasteboard generalPasteboard];
if (self.text) {
pastboard.string = self.text;
}else{
pastboard.string = self.attributedText.string;
}
self.backgroundColor = backgroundColor_;
}
#pragma mark UIMenuController消失时
- (void)menuControllerWillHide {
[self resignFirstResponder];
self.backgroundColor = backgroundColor_;
}
#pragma mark - UIResponder
#pragma mark 指定UICopyLabel能成为第一响应者
- (BOOL)canBecomeFirstResponder {
return YES;
}
#pragma mark 指定该UICopyLabel可以响应的方法(这里只需要使用复制)
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{
if (action == @selector(copyAction:)) {
return YES;
}
return NO;
}
#pragma mark - dealloc
- (void)dealloc {
[self resignFirstResponder];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerWillHideMenuNotification object:nil];
}
四、demo
1、storyboard中使用,创建UILabel控件,Class选择UICopyLabel即可。
2、代码调用
//init
self.codeCopyLabel = [[UICopyLabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.storyboardCopyLabel.frame)+50, 260, 40)];
self.codeCopyLabel.center = CGPointMake(self.storyboardCopyLabel.center.x, self.codeCopyLabel.center.y);
self.codeCopyLabel.selectedBackgroundColor = [UIColor colorWithRed:200/255.0 green:200/255.0 blue:200/255.0 alpha:1];
self.codeCopyLabel.textAlignment = NSTextAlignmentCenter;
self.codeCopyLabel.text = @"代码创建,长按复制我吧!";
[self.view addSubview:self.codeCopyLabel];
---------------------------- 分割线 -------------------------------
本篇通过创建UILabel的子类UICopyLabel实现了长按复制自身文字功能,只要让需要复制功能的Label继承UICopyLabel即可。但是它可能已经继承了其它封装好的子类,这时候我们可以换成下面这种方式实现。
UILabel+Copy:实现UILabel长按复制自身文字功能,与UICopyLabel不一样的实现方式。