How can I make a clickable link in an NSAttributedString? How can I make a clickable link in an NSAttributedString? ios ios

How can I make a clickable link in an NSAttributedString?


Use NSMutableAttributedString.

NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:@"Google"];[str addAttribute: NSLinkAttributeName value: @"http://www.google.com" range: NSMakeRange(0, str.length)];yourTextView.attributedText = str;

Edit:

This is not directly about the question but just to clarify, UITextField and UILabel does not support opening URLs. If you want to use UILabel with links you can check TTTAttributedLabel.

Also you should set dataDetectorTypes value of your UITextView to UIDataDetectorTypeLink or UIDataDetectorTypeAll to open URLs when clicked. Or you can use delegate method as suggested in the comments.


I found this really useful but I needed to do it in quite a few places so I've wrapped my approach up in a simple extension to NSMutableAttributedString:

Swift 3

extension NSMutableAttributedString {    public func setAsLink(textToFind:String, linkURL:String) -> Bool {        let foundRange = self.mutableString.range(of: textToFind)        if foundRange.location != NSNotFound {            self.addAttribute(.link, value: linkURL, range: foundRange)            return true        }        return false    }}

Swift 2

import Foundationextension NSMutableAttributedString {   public func setAsLink(textToFind:String, linkURL:String) -> Bool {       let foundRange = self.mutableString.rangeOfString(textToFind)       if foundRange.location != NSNotFound {           self.addAttribute(NSLinkAttributeName, value: linkURL, range: foundRange)           return true       }       return false   }}

Example usage:

let attributedString = NSMutableAttributedString(string:"I love stackoverflow!")let linkWasSet = attributedString.setAsLink("stackoverflow", linkURL: "http://stackoverflow.com")if linkWasSet {    // adjust more attributedString properties}

Objective-C

I've just hit a requirement to do the same in a pure Objective-C project, so here's the Objective-C category.

@interface NSMutableAttributedString (SetAsLinkSupport)- (BOOL)setAsLink:(NSString*)textToFind linkURL:(NSString*)linkURL;@end@implementation NSMutableAttributedString (SetAsLinkSupport)- (BOOL)setAsLink:(NSString*)textToFind linkURL:(NSString*)linkURL {     NSRange foundRange = [self.mutableString rangeOfString:textToFind];     if (foundRange.location != NSNotFound) {         [self addAttribute:NSLinkAttributeName value:linkURL range:foundRange];         return YES;     }     return NO;}@end

Example usage:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:"I love stackoverflow!"];BOOL linkWasSet = [attributedString setAsLink:@"stackoverflow" linkURL:@"http://stackoverflow.com"];if (linkWasSet) {    // adjust more attributedString properties}

Make Sure that the NSTextField's Behavior attribute is set as Selectable.Xcode NSTextField behavior attribute


I just created a subclass of UILabel to specially address such use cases. You can add multiple links easily and define different handlers for them. It also supports highlighting the pressed link when you touch down for touch feedback. Please refer to https://github.com/null09264/FRHyperLabel.

In your case, the code may like this:

FRHyperLabel *label = [FRHyperLabel new];NSString *string = @"This morph was generated with Face Dancer, Click to view in the app store.";NSDictionary *attributes = @{NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]};label.attributedText = [[NSAttributedString alloc]initWithString:string attributes:attributes];[label setLinkForSubstring:@"Face Dancer" withLinkHandler:^(FRHyperLabel *label, NSString *substring){    [[UIApplication sharedApplication] openURL:aURL];}];

Sample Screenshot (the handler is set to pop an alert instead of open a url in this case)

facedancer