【发布时间】:2015-06-20 15:45:47
【问题描述】:
在我的应用程序中,如果将某些内容添加到 NSPasteboard 中,我希望得到通知。如果我从任何其他程序复制文本,我希望我的应用程序知道它。
在某处我读到它不能那样做。我应该创建一个计时器并自己检查 NSPasteboard 的内容。
这是这样做的吗?或者有什么通知?
【问题讨论】:
标签: objective-c cocoa
在我的应用程序中,如果将某些内容添加到 NSPasteboard 中,我希望得到通知。如果我从任何其他程序复制文本,我希望我的应用程序知道它。
在某处我读到它不能那样做。我应该创建一个计时器并自己检查 NSPasteboard 的内容。
这是这样做的吗?或者有什么通知?
【问题讨论】:
标签: objective-c cocoa
是的,您基本上必须轮询粘贴板以查看其内容是否已更改。这并不理想,但有可能。基本上,您有一个每秒触发一次或两次并检查-[NSPasteboard changeCount] 的计时器。如果changeCount 发生变化,则意味着粘贴板的内容也发生了变化(或者至少有一个新所有者)。
【讨论】:
根据 Dave DeLong 提供的答案,我想出了类似的实现,但很快,这里是其要点的链接:PasteboardWatcher.swift
代码 sn-p 来自同一:
class PasteboardWatcher : NSObject {
// assigning a pasteboard object
private let pasteboard = NSPasteboard.generalPasteboard()
// to keep track of count of objects currently copied
// also helps in determining if a new object is copied
private var changeCount : Int
// used to perform polling to identify if url with desired kind is copied
private var timer: NSTimer?
// the delegate which will be notified when desired link is copied
var delegate: PasteboardWatcherDelegate?
// the kinds of files for which if url is copied the delegate is notified
private let fileKinds : [String]
/// initializer which should be used to initialize object of this class
/// - Parameter fileKinds: an array containing the desired file kinds
init(fileKinds: [String]) {
// assigning current pasteboard changeCount so that it can be compared later to identify changes
changeCount = pasteboard.changeCount
// assigning passed desired file kinds to respective instance variable
self.fileKinds = fileKinds
super.init()
}
/// starts polling to identify if url with desired kind is copied
/// - Note: uses an NSTimer for polling
func startPolling () {
// setup and start of timer
timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("checkForChangesInPasteboard"), userInfo: nil, repeats: true)
}
/// method invoked continuously by timer
/// - Note: To keep this method as private I referred this answer at stackoverflow - [Swift - NSTimer does not invoke a private func as selector](http://stackoverflow.com/a/30947182/217586)
@objc private func checkForChangesInPasteboard() {
// check if there is any new item copied
// also check if kind of copied item is string
if let copiedString = pasteboard.stringForType(NSPasteboardTypeString) where pasteboard.changeCount != changeCount {
// obtain url from copied link if its path extension is one of the desired extensions
if let fileUrl = NSURL(string: copiedString) where self.fileKinds.contains(fileUrl.pathExtension!){
// invoke appropriate method on delegate
self.delegate?.newlyCopiedUrlObtained(copiedUrl: fileUrl)
}
// assign new change count to instance variable for later comparison
changeCount = pasteboard.changeCount
}
}
}
注意: 在共享代码中,我试图确定用户是否复制了 文件 url 与否,提供的代码可以很容易地修改为其他一般 目的。
【讨论】: