'Caret position in NSTextField of NSTableView

I have a view based NSTableView of n rows and 1 column, with a monospaced font. When the user clicks within a row, I need to convert the caret position to a character index into the data populating that column. I currently trap the mouseDown event in a custom NSTextField, but am unable to obtain an index position of that location.

Code snippet:

    override func mouseDown(with event: NSEvent)
    {
        print (ME + ".\(#function)")

        let localPos = convert (event.locationInWindow, to: self)

        let cEditor = self.currentEditor() as? NSTextView
        
        let insertionPoint = cEditor?.characterIndexForInsertion(at: localPos)
                
        let location = cEditor?.selectedRange().location
    }

insertionPoint is equal to 416, which is the end position of the displayed data, location is 0, both of which don’t reflect the location of the caret.

Any help is greatly appreciated. At this point, I’ve resorted to wearing a bib to catch the drool from my exasperation.

Xcode 12.3 Swift 5



Solution 1:[1]

Based in large part on @Willeke, I have a solution to my problem. The updated code looks like this:

    override func mouseDown(with event: NSEvent)
    {
        super.mouseDown(with: event)
        
        let cEditor = self.currentEditor() as? NSTextView
        let localPos = convert (event.locationInWindow, to: nil)
        let insertionPoint = cEditor?.characterIndexForInsertion(at: localPos)           
        let location = cEditor?.selectedRange().location
    }

I added the call to super.mouseDown () as an initial step, and also changed the to: component of the convert to nil, both of which resulted in an accurate location index. The insertionPoint is 0, but location is accurate, and that solves my problem.

I think it was a mistake on my part to use IB for the initial NSTableView configuration as it gave me a lot of settings I didn't understand and couldn't appreciate the consequences. But @Willeke's comments led to the solution for this specific question. It was also a mistake to not implement this feature in its own localized project, as the amount of code in play was too large to post for a minimal reproducible set.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Hayseed