自从上次在macOS中输入NSTextView后如何检测用户不活动?

时间:2017-03-18 14:24:47

标签: swift macos timer textview

当用户没有键入特定的NSTextView 2秒钟时,我需要执行特定的方法(updateStatistics)。我需要这个,因为当文本特别大时,updateStatistics方法会导致输入延迟。

也许我可以在textDidChange()中存储用户结束数字的时间:

func textDidChange(_ notification: Notification) {
    startDate = Date()
    Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(self.updateStatistics), userInfo: nil, repeats: false)
}

然后了解updateStatistics方法中是否已经过了2秒:

func updateStatistics() {
    let currentDate = Date()
    let elapsed = currentDate.timeIntervalSince(startDate)
    if elapsed >= 2 {
        // update statistics code
    }
}

PS 已经有一个类似问题here的答案,但它适用于iOS和Objective-C。

1 个答案:

答案 0 :(得分:2)

您需要一个超时计时器,可以在用户按键时重新启动。

textDidChange中调用此方法。它会创建一个超时计时器(一次)并重新启动它,直到计时器触发。当计时器触发时,它将失效,您可以执行统计代码。按下键时,循环将再次开始。 GCD DispatchSourceTimer非常适用于此目的,因为与(NS)Timer不同,它可以重新启动。

var timeoutTimer : DispatchSourceTimer!

func startTimer()
{
    let delay : DispatchTime = .now() + .seconds(2)
    if timeoutTimer == nil {
        timeoutTimer = DispatchSource.makeTimerSource()
        timeoutTimer.scheduleRepeating(deadline: delay, interval: 0)
        timeoutTimer.setEventHandler {
            timeoutTimer.cancel()
            timeoutTimer = nil
            DispatchQueue.main.async {
                // do something after time out on the main thread
                self.updateStatistics()
            }
        }
        timeoutTimer.resume()
    } else {
        timeoutTimer.scheduleRepeating(deadline: delay, interval: 0)
    }
}