2

How to make the text as a hyperlink in NSTextView programmatically?

Like this:

Just click here to register

or like this:

Just http://example.com to register

I found this solution but it works only for iOS, not for macOS

  • 2
    Possible duplicate of [Simple clickable link in Cocoa and Swift](https://stackoverflow.com/questions/38340282/simple-clickable-link-in-cocoa-and-swift) – ielyamani Sep 15 '18 at 10:33
  • 1
    @Carpsen90 it is about NSTextField and it uses a storyboard, so it is not a programmatic way –  Sep 15 '18 at 10:36

2 Answers2

3

Try this:

let attributedString = NSMutableAttributedString(string: "Just click here to register")
let range = NSRange(location: 5, length: 10)
let url = URL(string: "https://www.apple.com")!

attributedString.setAttributes([.link: url], range: range)
textView.textStorage?.setAttributedString(attributedString)

// Define how links should look like within the text view
textView.linkTextAttributes = [
    .foregroundColor: NSColor.blue,
    .underlineStyle: NSUnderlineStyle.styleSingle.rawValue
]
Code Different
  • 82,550
  • 14
  • 135
  • 153
  • 2
    It works, thank you! Don't you also know how can I change the cursor to pointer when I hover the link? :) –  Sep 15 '18 at 15:22
  • 1
    The question was for MacOS not for iOS – StNickolay Jan 06 '21 at 10:51
  • Hi, on Swift 5 developing a macOS app, this does not produce a clickable link. Anything I'm missing to get it working? The text is blue an underlined properly but it's not clickable for some reason. – user3064009 Apr 18 '21 at 03:06
0

If you needed set Font Size for links use this ->

    let input = "Your string with urls"
      
      let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
      let matches = detector.matches(in: input, options: [], range: NSRange(location: 0, length: input.utf16.count))
      
      let attributes = [NSAttributedString.Key.font: NSFont.systemFont(ofSize: 15)]
      let attributedString = NSMutableAttributedString(string: input, attributes: attributes)
      if matches.count > 0{
           for match in matches {
                guard let range = Range(match.range, in: input) else { continue }
                let url = input[range]
                
                attributedString.setAttributes([.link: url, .font: NSFont.systemFont(ofSize: 15)], range: match.range)
           
           
           }
      }
      
      youTextView.textStorage?.setAttributedString(attributedString)