Reputation:
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
Upvotes: 2
Views: 2401
Reputation: 343
Swift 5 / macOS 12 solution to make the link clickable and have the same font any NSTextField's you display in the same window:
Define some NSTextView IBOutlet (mine is called tutorialLink
):
@IBOutlet weak var tutorialLink : NSTextView!
Then here's the styling code in one function:
fileprivate func initTutorialLink() {
let attributedString = NSMutableAttributedString(string: "Here's a tutorial on how to set up a Digital Ocean S3 account.")
// Set font for entire string
let fontAttributes = [NSAttributedString.Key.font: NSFont.systemFont(ofSize: 13)]
let range2 = NSRange(location: 0, length: 61)
attributedString.setAttributes(fontAttributes, range: range2)
// Set url and same font for just the link range
let range = NSRange(location: 21, length: 40)
let url = URL(string: tutorialUrl)!
attributedString.setAttributes([.link: url, NSAttributedString.Key.font:NSFont.systemFont(ofSize: 13)], range: range)
// Store the attributed string
tutorialLink.textStorage?.setAttributedString(attributedString)
// Mark how link text should be colored and underlined
tutorialLink.linkTextAttributes = [
.foregroundColor: NSColor.systemBlue,
.underlineStyle: NSUnderlineStyle.single.rawValue
]
// Give non-linked text same color as other labels
tutorialLink.textColor = .labelColor
}
In IB, you obviously need to connect your NSTextView (called Scrollable Text View in the Objects Library) to the IBOutlet. Less obviously, you need to click the box to make the NSTextView Selectable
. I don't know why exactly, but if it's not Selectable
then your link will not react when clicked.
Upvotes: 0
Reputation: 184
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)
Upvotes: 1
Reputation: 93161
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
]
Upvotes: 3