Search code examples
iosswiftuitextviewnsattributedstring

Manually formatting url starting with http or https in string for UITextView of iOS/Xcode


I would like to select a bunch of urls only starting with http or https from a string. In UITextView, .dataDetectorTypes can be set to .link for making all urls into blue underlined text.

For example, from "www.google.com and https://www.gogole.com and http://www.google.com as well as "google.com" I would like to make only url starting with https or http into blue underlined text and keep them in the same original sentence, if not in a new sentence with modified selected urls. Is it possible for such approach? Or which way i could implement that.?


Solution

  • A way to do so:
    Use a NSMutableAttributedString.
    Use NSDataDetector to find all the links.
    Enumerate (enumerateMatches(in:options:range:using:)) and edit according to your rule if you want to add or not the NSAttributedStringKey.link.

    let initialString = "www.google.com and https://www.gogole.com and http://www.google.com as well as \"google.com\""
    let linkDetector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
    
    let attributedString = NSMutableAttributedString(string: initialString)
    
    linkDetector.enumerateMatches(in: attributedString.string,
                                  options: [],
                                  range: NSRange(location: 0, length: attributedString.string.utf16.count)) { (match, flags, stop) in
                                    if let match = match, match.resultType == NSTextCheckingResult.CheckingType.link, let url = match.url {
                                        if let range = Range(match.range, in: attributedString.string) {
                                            let substring = attributedString.string[range]
                                            if substring.hasPrefix("http") {
                                                attributedString.addAttribute(.link, value: url, range: match.range)
                                            }
                                        }
                                    }
    }
    

    I used the test substring.hasPrefix("http"), but you can use the one you want.

    Output:

    attributedString:
    www.google.com and {
    }https://www.gogole.com{
        NSLink = "https://www.gogole.com";
    } and {
    }http://www.google.com{
        NSLink = "http://www.google.com";
    } as well as "google.com"{
    }