URL Linking in a non editable NSTextView

You’re likely here because you thought you could just do this:

NSTextView *textView = [NSTextView new];
[textView setEditable:NO];
[textView setAutomaticLinkDetectionEnabled:YES];
[textView setString:@"homesite: http://travisjeffery.com/ and twitter: http://twitter.com/travisjeffery"];
// ...

And you’d have clickable links in your NSTextView. Nope. setAutomaticLinkDetectionEnabled: works only when the NSTextView is editable.

The simplest solution is to build an NSAttributedString with links found using an NSDataDetector. Like so:

[textView.textStorage setAttributedString:[self autoLinkURLs:@"homesite: http://travisjeffery.com/ and twitter: http://twitter.com/travisjeffery"]];

// ..

- (NSAttributedString *)autoLinkURLs:(NSString *)string {
    NSMutableAttributedString *linkedString = [[NSMutableAttributedString alloc] initWithString:string];

    NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
    [detector enumerateMatchesInString:string options:0 range:NSMakeRange(0, string.length) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) {
        if (match.URL) {
            NSDictionary *attributes = @{ NSLinkAttributeName: match.URL };
            [linkedString addAttributes:attributes range:match.range];
        }
    }];

    return [linkedString copy];
}

Follow me on Twitter to keep up with what I’ve learned building my personal finance tool, Stash.

Subscribe to my mailing list to learn more about technology and business.

Your email will never be shared with anyone else.

Read more posts …
Written: November 9th, 2013
Categories: appkit, detection, link, mac, nstextview