【问题标题】:Attributed string hyperlink not showing proper cursor属性字符串超链接未显示正确的光标
【发布时间】:2014-06-26 18:48:37
【问题描述】:

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

我已经搜索了一段时间,似乎没有一个简单的答案来解决这个问题,这令人困惑,因为超链接似乎很常见。人们以前曾建议使用超链接的 NSButtons(那么如何在悬停时获得下划线?)和 NSTextViews,但这似乎有点 hack-y。在 OSX 编程中做超链接的正确方法是什么?

注意:我偶然发现了 this article,它显示了一种使用 textviews 和“类别”的方法。这是做事的正确方法吗?我想编写可维护且干净的代码。

谢谢!

【问题讨论】:

    标签: objective-c macos cocoa nstextfield


    【解决方案1】:

    基于 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())
        }
    }
    

    【讨论】:

      【解决方案2】:

      好问题! OSX 控件中的超链接虽然很实用,但看起来有点笨拙。

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

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

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

      【讨论】:

      • NSTextField 在第一次点击之前没有焦点很有意义,因为这是我在玩它时观察到的确切行为。很混乱!我以前看过那篇文章,但我尝试了接受的答案,但它没有用(我不知道为什么)。我没有理由相信子类化会解决问题(而且它看起来很乱),但如果这是唯一的选择,我想我将不得不这样做。
      • 如果您发布您自己的具体答案,我不会生气,但我相当确定您的具体问题类似于将光标更改为任何其他 NSView 子类。虽然我不认为这是重复的——也许有更好的方法。
      • 我没有注意到 addCursorRect:cursor: 是 NSView 的子类,所以它可能会起作用。但是,想象一下 NSAttributedString 中的超链接要环绕一行,那么 NSRect 将不起作用 - 你需要其中的两个。
      • 对。使用NSView bounds 将在整个矩形视图上更改光标。同样,我最终注册了整个表格单元格中的点击,而不是最终获得了可点击的链接。噗。
      • 好的,我让它工作了。子类化 NSButton 确实有效(根据您链接的相关问题中的最后一个示例),即使接受的答案没有!谢谢。
      猜你喜欢
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-30
      • 1970-01-01
      • 2011-11-11
      • 2016-04-10
      • 2019-03-20
      相关资源
      最近更新 更多