Search code examples
iosios6uitextview

UITextView hangs on very long pastes - how to catch and avoid?


In the course of developing an app someone submitted a bug report to me - "Cannot paste long text into text field". Sure enough, it hangs with the "Paste" bubble remaining blue from the tap and nothing ever happening. I experimented a little and found that everything works with a roughly 60,000 character file (and it would not take a worryingly long time), but 65537 would kill it every time.

I experimented further and found some third party apps as well as the "Notes" app show the same behaviour.

If this is a real problem in UITextView (in iOS6) I don't expect to be able to fix it so that huge text can be pasted in but I would like to avoid the hang if possible. Can anyone suggest a way of catching the text before it hangs the UITextView?

edit: Thanks to rmaddy, here's what I used to make it work:

#import <MobileCoreServices/UTCoreTypes.h>

#define kUITextViewMaximumPaste (65000)

...

- (void)paste:(id)sender {

  UIPasteboard *pb = [UIPasteboard generalPasteboard];
  NSString *type = (NSString *)kUTTypeText;
  if ([pb containsPasteboardTypes:@[type]]) {

    NSString *txt = [pb valueForPasteboardType:type];
    if([txt length] > kUITextViewMaximumPaste) {

      [pb setValue:[txt substringToIndex:kUITextViewMaximumPaste] forPasteboardType:type];
    }
  }

  [super paste:sender];
}

Solution

  • I had a need to do something similar but for different reasons. What I did is implement the paste: method in my custom view that contained the UITextView. As matt suggested in the comment, it may be best to create your own custom subclass of UITextView and implement the paste: method:

    - (void)paste:(id)sender {
        if ([[UIPasteboard generalPasteboard] containsPasteboardTypes:[NSArray arrayWithObjects:(NSString *)kUTTypeUTF8PlainText, nil]]) {
            NSString *txt = [[UIPasteboard generalPasteboard] valueForPasteboardType:(NSString *)kUTTypeUTF8PlainText];
            if (txt.length > 65535) {
                // oops - too long
                // either truncate or ignore
    
                return;
            }
        }
    
        [super paste:sender];
    }
    

    You may also need to handle other pasteboard types. If a user copies and paste part of a webpage, you may see other types being pasted.