Question

I have a UITextView (in edit mode) with few images (as NSTextAttachment). I'd like to intercept touch events on these.

I have set a delegate on the UITextView but textView:shouldInteractWithTextAttachment:inRange: is never called.

(from the forums it seems that the UITextView's editable property should be NO for this to work, but not as per the official documentation)

The editor looks like this: Editor

Was it helpful?

Solution

As you mentioned, textView:shouldInteractWithTextAttachment:inRange: is not meant to work for editable text views. A way around this is to implement your own UITapGestureRecognizer and do something like this:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    if (self.state == UIGestureRecognizerStateFailed) return;

    UITouch *touch = [touches anyObject];
    UITextView *textView = (UITextView*) self.view;
    NSTextContainer *textContainer = textView.textContainer;
    NSLayoutManager *layoutManager = textView.layoutManager;

    CGPoint point = [touch locationInView:textView];
    point.x -= textView.textContainerInset.left;
    point.y -= textView.textContainerInset.top;

    NSUInteger characterIndex = [layoutManager characterIndexForPoint:point inTextContainer:textContainer fractionOfDistanceBetweenInsertionPoints:nil];

    if (characterIndex >= textView.text.length)
    {
        self.state = UIGestureRecognizerStateFailed;
        return;
    }

    _textAttachment = [textView.attributedText attribute:NSAttachmentAttributeName atIndex:characterIndex effectiveRange:&_range];
    if (_textAttachment)
    {
        return;
    }
    _textAttachment = nil;
}

Then you add this gesture recogniser to your text view and when the gesture is recognized you ask for the _textAttachment value.

Bear in mind that characterIndexForPoint:inTextContainer: fractionOfDistanceBetweenInsertionPoints: returns the nearest character index. You might want to check if the point is inside the attachment depending on what you're planning to do.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top