Cocoa和Swift中的简单可点击链接

时间:2016-07-12 23:16:20

标签: swift cocoa hyperlink

我在swift for mac 10.11中编写了一个桌面应用程序,我想添加一个指向about页面的链接。

非常喜欢这样:https://developer.apple.com/library/mac/qa/qa1487/_index.html

我找不到好的教程或参考资料。

非常感谢任何帮助

6 个答案:

答案 0 :(得分:4)

Swift 4,xCode 9

@IBDesignable
class HyperlinkTextField: NSTextField {

    @IBInspectable var href: String = ""

    override func resetCursorRects() {
        discardCursorRects()
        addCursorRect(self.bounds, cursor: NSCursor.pointingHand)
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        // TODO:  Fix this and get the hover click to work.

        let attributes: [NSAttributedStringKey: Any] = [
            NSAttributedStringKey.foregroundColor: NSColor.linkColor,
            NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue as AnyObject
        ]
        attributedStringValue = NSAttributedString(string: self.stringValue, attributes: attributes)
    }

    override func mouseDown(with theEvent: NSEvent) {
        if let localHref = URL(string: href) {
            NSWorkspace.shared.open(localHref)
        }
    }
}

答案 1 :(得分:3)

最简单的方法是将NSTextField子类化以创建HyperlinkTextField。以下是一个例子:

首先,让我们为您的项目添加一个HyperlinkTextField类:

// HyperlinkTextField.swift

import Cocoa

@IBDesignable
class HyperlinkTextField: NSTextField {
    @IBInspectable var href: String = ""

    override func awakeFromNib() {
        super.awakeFromNib()

        let attributes: [String: AnyObject] = [
            NSForegroundColorAttributeName: NSColor.blueColor(),
            NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle.rawValue
        ]
        self.attributedStringValue = NSAttributedString(string: self.stringValue, attributes: attributes)
    }

    override func mouseDown(theEvent: NSEvent) {
        NSWorkspace.sharedWorkspace().openURL(NSURL(string: self.href)!)
    }
}

接下来,在Interface Builder中,将标签从Object库拖到窗口。

选择该标签,转到菜单查看>公用事业>显示Identity Inspector (或按Cmd + Opt + 3)并将班级更改为HyperlinkTextField

Identity Inspector

转到属性检查器Cmd + Opt + 4)并将Href设置为您要访问的网址。

Attributes Inspector

标签在Interface Builder中显示黑色文本,但运行应用程序时一切都会正常。单击标签将打开默认浏览器中的链接。

我无法实现的一件事是将HyperlinkTextField显示为蓝色并在Interface Builder中加下划线。关于如何做到这一点的评论是受欢迎的。

答案 2 :(得分:2)

正是我所需要的。这是Swift3版本:

import Cocoa

@IBDesignable
class HyperTextField: NSTextField {
    @IBInspectable var href: String = ""

    override func awakeFromNib() {
        super.awakeFromNib()

        let attributes: [String: AnyObject] = [
            NSForegroundColorAttributeName: NSColor.blue,
            NSUnderlineStyleAttributeName: NSUnderlineStyle.styleSingle.rawValue as AnyObject
        ]
        self.attributedStringValue = NSAttributedString(string: self.stringValue, attributes: attributes)
    }

    override func mouseDown(with event: NSEvent) {
        NSWorkspace.shared().open(URL(string: self.href)!)
    }
}

答案 3 :(得分:2)

修改了现有的答案,允许标签文字的子字符串变为带下划线和蓝色,因此您可以执行以下操作:This就是答案

// A text field that can contain a hyperlink within a range of characters in the text.
@IBDesignable
public class SubstringLinkedTextField: NSTextField {
    // the URL that will be opened when the link is clicked.
    public var link: String = ""
    @available(*, unavailable, message: "This property is reserved for Interface Builder. Use 'link' instead.")
    @IBInspectable public var HREF: String {
        get {
            return self.link
        }
        set {
            self.link = newValue
            self.needsDisplay = true
        }
    }

    // the substring within the field's text that will become an underlined link. if empty or no match found, the entire text will become the link.
    public var linkText: String = ""
    @available(*, unavailable, message: "This property is reserved for Interface Builder. Use 'linkText' instead.")
    @IBInspectable public var LinkText: String {
        get {
            return self.linkText
        }
        set {
            self.linkText = newValue
            self.needsDisplay = true
        }
    }

    override public func awakeFromNib() {
        super.awakeFromNib()

        self.allowsEditingTextAttributes = true
        self.isSelectable = true

        let url = URL(string: self.link)
        let attributes: [NSAttributedStringKey: AnyObject] = [
            NSAttributedStringKey(rawValue: NSAttributedStringKey.link.rawValue): url as AnyObject
        ]
        let attributedStr = NSMutableAttributedString(string: self.stringValue)

        if self.linkText.count > 0 {
            if let range = self.stringValue.indexOf(substring: self.linkText) {
                attributedStr.setAttributes(attributes, range: range)
            } else {
                attributedStr.setAttributes(attributes, range: NSMakeRange(0, self.stringValue.count))
            }
        } else {
            attributedStr.setAttributes(attributes, range: NSMakeRange(0, self.stringValue.count))
        }
        self.attributedStringValue = attributedStr
    }
}

答案 4 :(得分:1)

let link = NSTextField()
link.isBezeled = false
link.drawsBackground = false
link.isEditable = false
link.isSelectable = true
link.allowsEditingTextAttributes = true
let url = URL(string: "http://www.google.com")
let linkTextAttributes: [NSAttributedStringKey: Any] = [
        NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue,
        NSAttributedStringKey.foregroundColor: NSColor.blue,
        NSAttributedStringKey.link: url as Any
            ]
let string = "whatever"
link.attributedStringValue = NSAttributedString(string: string, attributes: linkTextAttributes)
window.contentView?.addSubview(link)

答案 5 :(得分:0)

迅速4.2

class HyperlinkTextField: NSTextField {


private var detector: NSDataDetector!

override func awakeFromNib() {
    super.awakeFromNib()
     detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
}


func setText(text: String ){
    let matches = detector.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count))

    for match in matches {
        guard let range = Range(match.range, in: text) else { continue }
        let url = text[range]
        let attributedString = NSMutableAttributedString(string: text)
        attributedString.addAttribute(.link, value: url, range: match.range)
        self.attributedStringValue = attributedString
    }
}

}