Link in a label or a text view and macOS

How to make a link in a label or a text view?

I could find different solutions for iOS but not for macOS.

For instance, this works in iOS but not in macOS:

Code Block
let attributedString = NSMutableAttributedString(string: "Just click here to register")
let range = NSRange(location: 5, length: 10)
let url = URL(string: "https://www.google.com")!
attributedString.setAttributes([.link: url], range: range)
textView1.textStorage?.setAttributedString(attributedString)
textView1.linkTextAttributes = [
.foregroundColor: NSColor.blue,
.underlineStyle: NSUnderlineStyle.styleSingle.rawValue
]


In macOS it gives me two errors:
Value of type NSScrollView has no member textStorage   
Value of type NSScrollView has no member linkTextAttributes

Accepted Reply

In macOS it gives me two errors:
Value of type NSScrollView has no member textStorage  
Value of type NSScrollView has no member linkTextAttributes

Seems you have put a Scrollable Text View into your view controller and connected it to an IBOutlet.

There may be this line in your code:
Code Block
@IBOutlet weak var textView1: NSScrollView!

Your outlet textView1 is connected to an NSScrollView, not an NSTextView.


You can find the actual instance of NSTextView when you open up the view hierarchy in the Outline view (left side of Interface Builder):
Code Block
  ▼ Text View1
   ▼ Clip View
    ▼ Text View <-- This is the actual `NSTextView`

Ctrl-drag from the Text View to your view controller and create another IBOutlet.

Assuming you named it contentTextView, you will have this line:
Code Block
@IBOutlet var contentTextView: NSTextView!

You can name it as you like, but the important thing is that Xcode has automatically chosen NSTextView for its type.

With this right outlet, your code would work as expected:
Code Block
let attributedString = NSMutableAttributedString(string: "Just click here to register")
let range = NSRange(location: 5, length: 10)
let url = URL(string: "https://www.google.com")!
attributedString.setAttributes([.link: url], range: range)
contentTextView.textStorage?.setAttributedString(attributedString)
contentTextView.linkTextAttributes = [
.foregroundColor: NSColor.blue,
.underlineStyle: NSUnderlineStyle.single.rawValue //<- Xcode suggested me to fix this line
]


Replies

Did you try to put a tagGesture on the label ?

In macOS it gives me two errors:
Value of type NSScrollView has no member textStorage  
Value of type NSScrollView has no member linkTextAttributes

Seems you have put a Scrollable Text View into your view controller and connected it to an IBOutlet.

There may be this line in your code:
Code Block
@IBOutlet weak var textView1: NSScrollView!

Your outlet textView1 is connected to an NSScrollView, not an NSTextView.


You can find the actual instance of NSTextView when you open up the view hierarchy in the Outline view (left side of Interface Builder):
Code Block
  ▼ Text View1
   ▼ Clip View
    ▼ Text View <-- This is the actual `NSTextView`

Ctrl-drag from the Text View to your view controller and create another IBOutlet.

Assuming you named it contentTextView, you will have this line:
Code Block
@IBOutlet var contentTextView: NSTextView!

You can name it as you like, but the important thing is that Xcode has automatically chosen NSTextView for its type.

With this right outlet, your code would work as expected:
Code Block
let attributedString = NSMutableAttributedString(string: "Just click here to register")
let range = NSRange(location: 5, length: 10)
let url = URL(string: "https://www.google.com")!
attributedString.setAttributes([.link: url], range: range)
contentTextView.textStorage?.setAttributedString(attributedString)
contentTextView.linkTextAttributes = [
.foregroundColor: NSColor.blue,
.underlineStyle: NSUnderlineStyle.single.rawValue //<- Xcode suggested me to fix this line
]


I did not notice that I had the wrong Outlet. It seems that only happens with macOS. in iOS I did not had that problem. Thank you!

Do you know how to change the cursor on hover the link?

Do you know how to change the cursor on hover the link?

Frankly, I did not know how, but could find some articles like this soon.
How to change cursor on hover NSTextView? Swift 4, Xcode 9.4

Try adding an attribute to linkTextAttributes.
Code Block
contentTextView.linkTextAttributes = [
.foregroundColor: NSColor.blue,
.underlineStyle: NSUnderlineStyle.single.rawValue,
.cursor: NSCursor.pointingHand, //<-
]



This works very well. Thank you!

.cursor: NSCursor.pointingHand