2

I'm dynamically building views and printing attributed text on them using drawInRect:. Some of the text may include web links. How can I detect taps on web links so I can load the link in a UIWebView? I'm not using a UILabel, UITextView or UITextField to display the text because the text includes a mixture of text and images.

This is some of the code in drawRect for my UIView subclass that draws the text.

//draw the text

    NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:self.message.text];

    [attString beginEditing];

    NSArray *arrString = [attString.string componentsSeparatedByString:@" "];
    for (NSString *str in arrString)
    {
        if ([str rangeOfString:@"http://" options:NSCaseInsensitiveSearch].location != NSNotFound ||
            [str rangeOfString:@".com"    options:NSCaseInsensitiveSearch].location != NSNotFound ||
            [str rangeOfString:@".gov"    options:NSCaseInsensitiveSearch].location != NSNotFound ||
            [str rangeOfString:@".org"    options:NSCaseInsensitiveSearch].location != NSNotFound ||
            [str rangeOfString:@".edu"    options:NSCaseInsensitiveSearch].location != NSNotFound ||
            [str rangeOfString:@".net"    options:NSCaseInsensitiveSearch].location != NSNotFound ||
            [str rangeOfString:@".xxx"    options:NSCaseInsensitiveSearch].location != NSNotFound)
        {
            NSRange rng = [attString.string rangeOfString:str];

            NSString *url;

            if ([str rangeOfString:@"http://"  options:NSCaseInsensitiveSearch].location == NSNotFound &&
                [str rangeOfString:@"https://" options:NSCaseInsensitiveSearch].location == NSNotFound)
            {
                url = [NSString stringWithFormat:@"http://%@", str];
            }
            else
            {
                url = str;
            }

            [attString addAttribute:NSLinkAttributeName value:[NSURL URLWithString:url] range:rng];
        }
    }

    [attString endEditing];

    CGSize theSize;
    theSize = [attString.string sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:CGSizeMake(CHAT_TEXT_WIDTH, FLT_MAX) lineBreakMode:NSLineBreakByWordWrapping];
    [[UIColor blackColor] set];
    CGRect textRect = CGRectMake(0, 0, theSize.width, theSize.height);
    textRect.origin.x += 10;
    textRect.origin.y += 10;

    if (self.type == MESSAGE_BOX_RECEIVE) {
        textRect.origin.x += ARROW_WIDTH;
    }

    [attString drawInRect:textRect];

Thanks for any help...

SeanT
  • 1,741
  • 1
  • 16
  • 24
  • This might give you some ideas. http://stackoverflow.com/questions/13888941/nsattributedstring-tappable-ios – sangony Feb 07 '14 at 02:27
  • Can you post your code? I can suggest some ideas, but it really depends on how your custom views work. – WolfLink Feb 07 '14 at 02:33
  • @WolfLink I edited my post to include the code for how I draw the text. Thanks. – SeanT Feb 10 '14 at 21:08

1 Answers1

3

What you want to do is draw the text with TextKit (introduced in iOS 7). This allows you to interpret taps by way of TextKit as well.

Here's a downloadable example project where I display a list of words and detect which word the user tapped on (and I even respond by momentarily highlighting the word):

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch10p543drawingWithTextKit/ch23p815attributedStringDrawing3/StyledText.swift

matt
  • 515,959
  • 87
  • 875
  • 1,141