UICopyLabel:简单实现Label长按复制文字功能

一、效果图

UICopyLabel:简单实现Label长按复制文字功能_第1张图片

二、 会用到的几个类

/**
 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即可。

UICopyLabel:简单实现Label长按复制文字功能_第2张图片

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不一样的实现方式。


你可能感兴趣的:(iOS-控件)