UILabel实现长按复制功能

1. 创建 UILabel 的子类

@interface YYCopyLabel : UILabel

@property (nonatomic, assign) BOOL copyEnabled;

@end

2. 增加 UILongPressGestureRecognizer 手势

- (void)setCopyEnabled:(BOOL)copyEnabled
{
    _copyEnabled = copyEnabled;
    
    // 确保 UILabel 可交互
    self.userInteractionEnabled = copyEnabled;
    
    if (copyEnabled && !self.longPressGR) {
        self.longPressGR = [[UILongPressGestureRecognizer alloc] initWithTarget:self
                                                                         action:@selector(handleLongPressGesture:)];
        [self addGestureRecognizer:self.longPressGR];
    }
    
    if (self.longPressGR) {
        self.longPressGR.enabled = copyEnabled;
    }
}

- (void)handleLongPressGesture:(UILongPressGestureRecognizer *)longPressGR
{
    if (longPressGR.state == UIGestureRecognizerStateBegan) {
        [self becomeFirstResponder];
        [[UIMenuController sharedMenuController] setTargetRect:self.frame inView:self.superview];
        [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
    }
}

3. 实现 UIMenuController 的相关协议

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    // 自定义响应UIMenuItem Action,例如你可以过滤掉多余的系统自带功能(剪切,选择等),只保留复制功能。
    return (action == @selector(copy:));
}

- (void)copy:(id)sender
{
    [[UIPasteboard generalPasteboard] setString:self.text];
}

4. 使用UIMenuController出现UIViewControllerHierarchyInconsistency crash

  • Exception log: UICompatibilityInputViewController的父控制器必须是UIInputWindowController,不能是其他自定义的控制器。
'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<UICompatibilityInputViewController: 0x7f9b37f00fa0> should have parent view controller:<ClipboardLabelViewController: 0x7f9b3b009b90> but requested parent is:<UIInputWindowController: 0x7f9b3801d400>'
  • 崩溃原因:调用UIMenuController控制器的视图层级树(view tree)存在命名为inputView的view。上面例子是因为ClipboardLabelViewController 定义了inputView。
@property (nonatomic, strong) UIView *inputView;
  • 解决办法:找出自定义inputView,修改其命名,例如你可以改成myInputView

5. YYCopyLabelDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 先上图,这是最终功能实现效果图 其实很简单,首先创建一个继承了UILabel的MLLongPressLabel,然...
    codermali阅读 2,110评论 0 3
  • 标签(空格分隔): IOS 在iOS8 之后, 我们发现UILabel不在为我们提供长按弹出复制等操作了, 我们来...
    袁俊亮技术博客阅读 1,802评论 0 0
  • 务实中寻求那么一点点的小浪漫
    宁静致远_3962阅读 71评论 0 0
  • 终于到了除夕的晚上,马上开始我已经期待了很久的重头戏。到了晚上的时候八点多时,乡下的天已经黑尽了,我和哥哥来到...
    637ea2df2016阅读 436评论 0 2
  • 幸存者36季网上评分并不太高,不过目前来看似乎没有网上说的那么差劲,只不过确实是有些人过于自大,策略也不太好,以至...
    一木一心阅读 394评论 0 1