归因字符串超链接未显示正确的游标

时间:2014-06-26 18:48:37

标签: objective-c macos cocoa nstextfield

我正在关注 example from Apple 在NSTextField中创建超链接(通过属性字符串),虽然超链接本身有效,但游标存在问题。也就是说,当您将鼠标悬停在超链接上时,它会显示正常的工字形光标,直到您单击它为止。单击一次后,它会显示正确的指向手形光标。

我已经搜索了一段时间,这个问题似乎没有一个简单的答案,这是令人困惑的,因为超链接看起来好像很常见。人们已经建议使用超链接的NSButton(你如何在悬停下划线,然后呢?)和之前的NSTextViews,但这似乎有些黑客攻击。在OSX编程中执行超链接的正确方法是什么?

注意:我偶然发现了 this article ,这显示了使用textviews和“category”执行此操作的方法。这是正确的做事方式吗?我想编写可维护和干净的代码。

谢谢!

2 个答案:

答案 0 :(得分:3)

好问题! OSX控件中的超链接虽然功能齐全,但看起来有点笨拙。

我相信这是因为NSTextField在第一次点击之前没有焦点。

可能的解决方案是use this related question's answer(s).我要复制并粘贴一些代码,但是那里的dscussion很有用。关于如何对视图进行子类化的最底层答案可能是最强大的。

NSCursor class methods包含其他可能的游标类型列表。

答案 1 :(得分:3)

基于Apple的例子和@ stevesliva的回答,这就是我想出的:

import Cocoa

extension NSAttributedString {

    /// Return an attributed string that looks like a hyperlink
    ///
    /// Based on code at <https://developer.apple.com/library/mac/qa/qa1487/_index.html>
    ///
    /// - parameters:
    ///    - string: text to be turned into a hyperlink
    ///    - URL: destination of the hyperlink
    /// - returns: `NSAttributedString`
    static func hyperlinkFromString(string: String, withURL URL: NSURL) -> NSAttributedString {

        let attrString = NSMutableAttributedString(string: string)
        let range = NSMakeRange(0, attrString.length)

        attrString.beginEditing()

        attrString.addAttribute(NSLinkAttributeName,
            value: URL.absoluteString,
            range: range)

        attrString.addAttribute(NSForegroundColorAttributeName,
            value: NSColor.blueColor(),
            range: range)

        attrString.addAttribute(NSUnderlineStyleAttributeName,
            value: NSNumber(int: Int32(NSUnderlineStyle.StyleSingle.rawValue)),
            range: range)

        attrString.fixAttributesInRange(range)

        attrString.endEditing()

        return attrString
    }
}

/// Subclass of NSTextField used to display hyperlinks
class HyperlinkTextField: NSTextField {
    /// Set content to be a hyperlink
    ///
    /// Based on code at <https://developer.apple.com/library/mac/qa/qa1487/_index.html>
    ///
    /// - parameters:
    ///    - title: text displayed in field
    ///    - URL: destination of hyperlink
    func setHyperlinkWithTitle(title: String, URL: NSURL) {
        allowsEditingTextAttributes = true
        selectable = true
        attributedStringValue = NSAttributedString.hyperlinkFromString(title,
            withURL: URL)
    }

    /// Always display a pointing-hand cursor
    override func resetCursorRects() {
        addCursorRect(bounds, cursor: NSCursor.pointingHandCursor())
    }
}