iOS - 复制 UITextView

iOS - Copying a UITextView

在我的应用程序中,用户可以互相发送消息。我在气泡图像中使用 UITextView 来显示聊天记录。

        [messageTextView setFrame:CGRectMake(padding, padding+5, size.width,     size.height+padding)];
        [messageTextView sizeToFit];
        messageTextView.backgroundColor=[UIColor clearColor];

        UIImage *img = [UIImage imageNamed:@"whiteBubble"];
        UIImageView *bubbleImage=[[UIImageView alloc] initWithImage:[img stretchableImageWithLeftCapWidth:24 topCapHeight:15]];

        messageTextView.editable=NO;

        [bubbleImage setFrame:CGRectMake(padding/2, padding+5,
                                         messageTextView.frame.size.width+padding/2, messageTextView.frame.size.height+5)];


        [cell.contentView addSubview:bubbleImage];
        [cell.contentView addSubview:messageTextView];

目前,当用户按住消息文本时,他们会看到 'Copy' 和 'Define' 选项,光标指向 select 文本。

但是,我更愿意使用基本的 iOS 消息传递选项,即按住聊天气泡以复制整条消息。如何实现?

我将子类化 UITextView 以实现您自己的复制菜单版本。您可以通过多种方式完成此操作,但一种可能的方式如下所示。

基本思想是文本视图设置一个 UILongPressGestureRecognizer,当检测到长按时将创建弹出菜单。

UILongPressGestureRecognizer 有几个默认的系统菜单,除非您告诉它们不要显示,否则它们会显示。这样做的方法是 return NO 对于您不想在 canPerformAction:withSender: 中处理的任何选择器。在这种情况下,我们 returning NO 除了我们的自定义 copyText: 选择器之外的任何选择器。

然后该选择器仅获取对常规 UIPasteboard 的引用并将其文本设置为 TextView 的文本。

在您的子类的实现中:

@implementation CopyTextView

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setup];
    }
    return self;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup {
    self.editable = NO;
    self.selectable = NO;

    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDetected:)];
    longPress.minimumPressDuration = 0.3f; // however long, in seconds, you want the user to have to press before the menu shows up
    [self addGestureRecognizer:longPress];
}

- (void)longPressDetected:(id)sender {
    [self becomeFirstResponder];

    UILongPressGestureRecognizer *longPress = (UILongPressGestureRecognizer *)sender;
    if (longPress.state == UIGestureRecognizerStateEnded) {
        UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Copy" action:@selector(copyText:)];

        UIMenuController *menuCont = [UIMenuController sharedMenuController];

        [menuCont setTargetRect:self.frame inView:self.superview];

        menuCont.arrowDirection = UIMenuControllerArrowDown;
        menuCont.menuItems = [NSArray arrayWithObject:menuItem];
        [menuCont setMenuVisible:YES animated:YES];
    }
}


- (BOOL)canBecomeFirstResponder { return YES; }

- (void)copyText:(id)sender {
    UIPasteboard * pasteboard = [UIPasteboard generalPasteboard];
    [pasteboard setString:self.text];
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if (action == @selector(copyText:)) return YES;
    return NO;
}

@end

有用的文档:

UILongPressGestureRecognizer Documentation

UIMenuController Documentation