繁体   English   中英

创建并响应NSTableView文本单元格内的超链接

[英]Create and Respond to a Hyperlink within a NSTableView Text Cell

我有一个程序,其中装有要上传的文件的NSTableView。 发送文件后,带有文件名称的文本单元将获得一个放置在其中的超链接(为数组数据提供了带有NSLinkAttributeName属性的NSMutableString)。 如何允许用户单击此链接在其默认浏览器中打开网页?

经过大量搜索并尝试了多种方法之后,这就是我提出的解决方案。

创建一个扩展NSTableViewCell的自定义类:

class TableViewCellCursor: NSTableCellView {

internal var active = false

//MARK: - View Life Cycle

override func awakeFromNib() {
    superview?.awakeFromNib()
    self.createTrackingArea()
}

//MARK: - IBActions

override func mouseEntered(theEvent: NSEvent) {
    if (NSCursor.currentCursor() == NSCursor.arrowCursor() && active) {
        NSCursor.pointingHandCursor().set()
    }
}

override func mouseExited(theEvent: NSEvent) {
    if (NSCursor.currentCursor() == NSCursor.pointingHandCursor() && active) {
        NSCursor.arrowCursor().set()
    }
}

//Informs the receiver that the mouse cursor has moved into a cursor rectangle.
override func cursorUpdate(event: NSEvent) {
    if (active) {
        NSCursor.pointingHandCursor().set()
    }
}

//MARK: - Util

func createTrackingArea() {
    var focusTrackingAreaOptions:NSTrackingAreaOptions = NSTrackingAreaOptions.ActiveInActiveApp
    focusTrackingAreaOptions |= NSTrackingAreaOptions.MouseEnteredAndExited
    focusTrackingAreaOptions |= NSTrackingAreaOptions.AssumeInside
    focusTrackingAreaOptions |= NSTrackingAreaOptions.InVisibleRect

    var focusTrackingArea:NSTrackingArea = NSTrackingArea(rect: NSZeroRect,
                                                        options: focusTrackingAreaOptions,
                                                        owner: self, userInfo: nil)
    self.addTrackingArea(focusTrackingArea)
}
}

当NSTableView选择更改时,检查第一响应者状态。 这是必要的,因为可以更改表的选择,即使它不是firstResponder:

func tableViewSelectionDidChange(aNotification: NSNotification) {
    if (self.firstResponder == filesToTransferTable) {
        changeSelectedRowTextColorTo(NSColor.whiteColor(), unselectedColor: NSColor.blueColor())
    } else {
        changeSelectedRowTextColorTo(NSColor.blackColor(), unselectedColor: NSColor.blueColor())
    }
}

func changeSelectedRowTextColorTo(selectedColor: NSColor, unselectedColor: NSColor) {
    let selectedRows = filesToTransferTable.selectedRowIndexes
    for (index, tableEntry) in enumerate (tableData) {
        if tableData[index]["FileName"] is NSMutableAttributedString {
            var name = tableData[index]["FileName"] as! NSMutableAttributedString
            var range = NSMakeRange(0, NSString(string:name.string).length)
            name.beginEditing()
            name.removeAttribute(NSForegroundColorAttributeName, range: range)

            if (selectedRows.containsIndex(index)) {
                name.addAttribute(NSForegroundColorAttributeName, value:selectedColor, range:range)
            } else {
                name.addAttribute(NSForegroundColorAttributeName, value:unselectedColor, range:range)
            }

            name.endEditing()
            tableData[index]["FileName"] = name
        }
        filesToTransferTable.reloadDataForRowIndexes(NSIndexSet(index: index), columnIndexes: NSIndexSet(index:0))
    }
}

添加KVO以便在FirstResponder更改时进行检查:

//This is somewhere in your code where you initialize things
//KVO for first responder behavior regarding tableView and updating attributedStrings' colors
self.addObserver(self, forKeyPath: "firstResponder", options: NSKeyValueObservingOptions.Old | NSKeyValueObservingOptions.New, context: nil)

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
            if (change[NSKeyValueChangeNewKey] is NSTableView) {
                changeSelectedRowTextColorTo(NSColor.whiteColor(), unselectedColor: NSColor.blueColor())
            } else if (change[NSKeyValueChangeOldKey] is NSTableView) {
                changeSelectedRowTextColorTo(NSColor.blackColor(), unselectedColor: NSColor.blueColor())
            }
        }

最后,检查主窗口(应用本身)是否在焦点上(如果不这样做,那么当窗口失去焦点时,颜色将不会正确更改):

//Put these in the same place as the KVO code
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "windowDidBecomeKey:",
                    name: NSWindowDidBecomeKeyNotification , object: self)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "windowDidResignKey:",
                    name: NSWindowDidResignKeyNotification , object: self)


    func windowDidBecomeKey(notification: NSNotification) {
        if (self.firstResponder == filesToTransferTable) {
            changeSelectedRowTextColorTo(NSColor.whiteColor(), unselectedColor: NSColor.blueColor())
        } else {
            changeSelectedRowTextColorTo(NSColor.blackColor(), unselectedColor: NSColor.blueColor())
        }
    }

    func windowDidResignKey(notification: NSNotification) {
        if (self.firstResponder == filesToTransferTable) {
            changeSelectedRowTextColorTo(NSColor.blackColor(), unselectedColor: NSColor.blueColor())
        }
    }

文本字段自动支持单击嵌入式链接,但前提是它们至少是可选的(如果不可编辑)。 因此,将您的文本字段设置为可选。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM