0

I am using TTTAttributedLabel to detect hyperlinks in my text so that I can make them clickable. My code does not work, and links aren't clickable. In fact, everything is clickable. I only want URL's to be clickable.

here is the regex:

static NSRegularExpression *websiteRegularExpression;
static inline NSRegularExpression * WebsiteRegularExpression() {
    if (!websiteRegularExpression) {
        websiteRegularExpression = [[NSRegularExpression alloc] initWithPattern:@"\b(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|!:,.;]*[A-Z0-9+&@#/%=~_|]" 
                                                                        options:NSRegularExpressionCaseInsensitive 
                                                                          error:nil];
    }

    return websiteRegularExpression;
}

Here is the implementation

-(void)setBodyText
{
    __block NSRegularExpression *regexp = nil;   
    NSString* labelText = [[message valueForKey:@"body"]gtm_stringByUnescapingFromHTML]; //@"http://www.google.com is a cool website";
    [self.bodyLabel setText:labelText afterInheritingLabelAttributesAndConfiguringWithBlock:^NSAttributedString *(NSMutableAttributedString *mutableAttributedString) {

        NSRange stringRange = NSMakeRange(0, [mutableAttributedString length]);
       /* regexp = WebsiteRegularExpression ();
        NSRange nameRange = [regexp rangeOfFirstMatchInString:[mutableAttributedString string] options:0 range:stringRange];
        UIFont *boldSystemFont = [UIFont boldSystemFontOfSize:18.0]; 
        CTFontRef boldFont = CTFontCreateWithName((CFStringRef)boldSystemFont.fontName, boldSystemFont.pointSize, NULL);
        if (boldFont) {
            [mutableAttributedString addAttribute:(NSString *)kCTFontAttributeName value:(id)boldFont range:nameRange];
            CFRelease(boldFont);
        }

        if (nameRange.location != NSNotFound)
            [mutableAttributedString replaceCharactersInRange:nameRange withString:[[[mutableAttributedString string] substringWithRange:nameRange] uppercaseString]];
        return mutableAttributedString;
        */

        regexp = WebsiteRegularExpression();
        [regexp enumerateMatchesInString:[mutableAttributedString string] options:0 range:stringRange usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {            
            UIFont *italicSystemFont = [UIFont italicSystemFontOfSize:18.0];
            CTFontRef italicFont = CTFontCreateWithName((CFStringRef)italicSystemFont.fontName, italicSystemFont.pointSize, NULL);
            if (italicFont) {
                [mutableAttributedString addAttribute:(NSString *)kCTFontAttributeName value:(id)italicFont range:result.range];
                CFRelease(italicFont);

                [mutableAttributedString addAttribute:(NSString*)kCTForegroundColorAttributeName value:(id)[[UIColor grayColor] CGColor] range:result.range];
            }
        }];

        return mutableAttributedString;

    }];


    regexp = WebsiteRegularExpression();
    NSRange linkRange = [regexp rangeOfFirstMatchInString:labelText options:0 range:NSMakeRange(0, [labelText length])];
    NSURL *url = [NSURL URLWithString:@"http://www.google.com"];
    [self.bodyLabel addLinkToURL:url withRange:linkRange];

    [Utils alignLabelWithTop:bodyLabel];
}
1
  • First, you said http, you regex includes more then http, secondly, try something like this: https?://.[^ ]+ Commented Aug 9, 2011 at 20:58

1 Answer 1

5

Why not just: myTextView.dataDetectorTypes = UIDataDetectorTypeLink;?

Sign up to request clarification or add additional context in comments.

3 Comments

I want to be able to open links in a custom view controller inside of my app, instead of kicking the user out to safari.
Right before: NSRange linkRange = [regexp rangeOfFirstMatchInString:labelText options:0 range:NSMakeRange(0, [labelText length])]; Can you check if labelText has been released? It looks like the labelText string is set to autorelease, so it may be gone by the time you set the range, so the range becomes everything.
Use the dataDetectorTypes property and set delegate to your controller. Then, in you controller, you can implement the delegate method attributedLabel:didSelectLinkWithURL: to do whatever you want it to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.