How to change cursor on hover NSTextView? Swift 4, Xcode 9.4

2.3k views Asked by At

I have a simple NSTextView, which looks like a hyperlink and I want to change the cursor on the pointer when the user hovers this NSTextView. How can I do it? I know about NSCursor, but apple docs suck and have no examples, I cannot get how to use it.

Here is my NSTextView:

let linkView = NSTextView()
    linkView.font = NSFont(name: "SF Pro Display", size: 13)
    linkView.isEditable = false
    linkView.isFieldEditor = false
    linkView.isHidden = false

    linkView.string = (URL(string: (data?.link)!)?.host)!

    let attributedString = NSMutableAttributedString(string: linkView.string)
    let range = NSRange(location: 0, length: linkView.string.count)
    let url = URL(string: (data?.link)!)

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

    linkView.linkTextAttributes = [.underlineStyle: NSUnderlineStyle.styleSingle.rawValue]
2

There are 2 answers

0
Mark Cao On

Try this, it works for me:

import Cocoa

class HyperlinkTextView: NSTextView {

    private(set) var href: String = ""

    //MARK: Override

    override func updateTrackingAreas() {
        for area in self.trackingAreas {
            self.removeTrackingArea(area)
        }
        self.addTrackingRect(self.bounds, owner: self, userData: nil, assumeInside:     false)
    }

    override func mouseDown(with event: NSEvent) {
        super.mouseDown(with: event)
        if let url = URL(string: self.href) {
            NSWorkspace.shared.open(url)
        }
    }

    override func mouseExited(with event: NSEvent) {
        super.mouseExited(with: event)
        //Added a pointing hand here
        self.addCursorRect(self.bounds, cursor: .pointingHand)
    }

    override func mouseEntered(with event: NSEvent) {
        super.mouseEntered(with: event)
        //Back to the system cursor
        self.removeCursorRect(self.bounds, cursor: .pointingHand)
    }

    //MARK: Public

    func setHref(name: String, link: String) {

        self.href = link

        let attrTitle = NSMutableAttributedString.init(string: name)
        let range = NSMakeRange(0, attrTitle.length)
        attrTitle.addAttributes([NSAttributedString.Key.link : NSURL.init(string: link)!], range: range)
        attrTitle.setAlignment(NSTextAlignment.center, range: range)
        self.linkTextAttributes = [
            .font: NSFont.systemFont(ofSize: 10.0),
            .foregroundColor: NSColor.blue,
            .underlineStyle: NSUnderlineStyle.single.rawValue,
        ]
        self.textStorage?.setAttributedString(attrTitle)

    }

}
1
Giles On

Add the cursor style to your linking text attributes:

link.linkTextAttributes = [.cursor: NSCursor.pointingHand]