2015-04-16 5 views
2

В моем приложении пользователи могут отправлять сообщения друг другу. Я использую UITextView внутри изображения пузыря для отображения истории чата.iOS - Копирование 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]; 

В настоящее время, когда пользователь держит вниз по тексту сообщения, они видят «Копировать» и «Определить» варианту с курсорами для выбора текста.

Однако я бы предпочел, чтобы базовая функция обмена сообщениями iOS удерживала пузырь в чате, чтобы скопировать все сообщение. Как это можно достичь?

+0

http://stackoverflow.com/questions/19884243/how-to-copy- string-to-clipboard – meth

ответ

3

Я бы подклассифицировал UITextView для реализации собственной версии меню копирования. Вы можете сделать это несколькими способами, но один из возможных способов, как показано ниже.

Основная идея состоит в том, что текстовое представление устанавливает UILongPressGestureRecognizer, что создаст всплывающее меню при обнаружении длинного нажатия.

UILongPressGestureRecognizer имеет несколько стандартных системных меню, которые будут отображаться, если вы не сообщите им об этом. Способ сделать это - вернуть NO для любых селекторов, которые вы не хотите обрабатывать в canPerformAction:withSender:. В этом случае мы возвращаем 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

+0

отличный ответ для меня, спасибо! где я должен отправить бесплатное пиво :) –

Смежные вопросы