【问题标题】:countdown before proceeding - swift继续前的倒计时 - 迅速
【发布时间】:2018-07-27 10:53:59
【问题描述】:

需要帮助来制作一个倒数计时器,直到它失效才能继续。它也不应该阻塞主线程。有什么建议吗?

private var currentCountdownSeconds = 3
private var countdownTimer = Timer()

private func performTimer() {

    if secondsToCountDown != 0 {
        print(secondsToCountDown)
        countdownTimer = Timer(timeInterval: 1, target: self, selector: #selector(handleCountdown), userInfo: nil, repeats: true)
    }

}

@objc private func handleCountdown() {
    previewView.countdownLabel.text = "\(currentCountdownSeconds)"
    currentCountdownSeconds -= 1
    print(secondsToCountDown)
    if secondsToCountDown == 0 {
        countdownTimer.invalidate()
    }
}

public func toggleMovieRecording() {
    handleTimer()
    videoCaptureLogic()
}

public func toggleCapturePhoto() {
    handleTimer()
    videoCaptureLogic()
}

【问题讨论】:

  • 那么,你的代码有什么问题?
  • 为什么你不直接给countDownTimer = Timer(timeInterval: currentCountdownSeconds, target: self, selector: #selector(handleCountdown), userInfo: nil, repeats: true) 并且在选择器被调用后让它失效?
  • @AhmadF 代码执行没有错误,但是,我不知道如何让代码等到计时器失效才能继续执行另一行代码。
  • @RakeshaShastri ,我相信您的解决方案会使选择器每 3 秒调用一次。我需要每秒更新一次标签,让它看起来像一个倒数计时器。
  • 只需将另一行代码放入handleCountdown()方法中countdownTimer.invalidate()行之后

标签: swift timer block completion


【解决方案1】:

如果你必须在多个地方使用倒计时,试试这个。

private var currentCountdownSeconds = 3
private var countdownTimer = Timer()

private func performTimer() {

    if secondsToCountDown != 0 {
        print(secondsToCountDown)
        countdownTimer = Timer(timeInterval: 1, target: self, selector: #selector(handleCountdown), userInfo: nil, repeats: true)
    }

}

@objc private func handleCountdown() {
    previewView.countdownLabel.text = "\(currentCountdownSeconds)"
    currentCountdownSeconds -= 1
    print(secondsToCountDown)
    if secondsToCountDown == 0 {
        countdownTimer.invalidate()
        NotificationCenter.default.post(notification: NSNotification.Name.init("TimeComplete")
    }
}

现在在您需要的任何类中实现通知的观察者。当倒计时完成并发布通知时,相应的选择器将处理该事件。

class Something {

    init() {
        NotificationCenter.default.addObserver(self, selector: #selector(timerCompleteAction), name: NSNotification.Name.init("TimerComplete"), object: nil)
    }

    @objc func timerCompleteAction() {
          //Do necessary actions
    }
}

Something 可以是您的具有视频捕获功能的班级,在这种情况下,将该代码写入timerCompleteAction。然后再次在您有音频捕获的类中,添加相同的观察者并添加选择器方法并执行音频捕获操作。

【讨论】:

  • 嗯,这很有趣。我对您的解决方案有所了解。给我一点时间尝试一下
  • 好的。如果您遇到困难,请告诉我。
【解决方案2】:

您可以使用 DispatchGroups。定时器启动时进组,定时器失效时离开组。

private var currentCountdownSeconds = 3
private var countdownTimer = Timer()
private let timerDispatchGroup = DispatchGroup() // Init DispatchGroup

private func performTimer() {

    if secondsToCountDown != 0 {
        print(secondsToCountDown)
        timerDispatchGroup.enter() // Enter DispatchGroup
        countdownTimer = Timer(timeInterval: 1, target: self, selector: #selector(handleCountdown), userInfo: nil, repeats: true)
    }

}

@objc private func handleCountdown() {
    previewView.countdownLabel.text = "\(currentCountdownSeconds)"
    currentCountdownSeconds -= 1
    print(secondsToCountDown)
    if secondsToCountDown == 0 {
        countdownTimer.invalidate()
        timerDispatchGroup.leave() // Leave DispatchGroup
    }
}

public func toggleMovieRecording() {
    performTimer() // I guess it should be performTimer instead of handleTimer?
    timerDispatchGroup.notify(queue: .main) { videoCaptureLogic() } // Closure 
}

public func toggleCapturePhoto() {
    performTimer()
    timerDispatchGroup.notify(queue: .main) { videoCaptureLogic() }
}

【讨论】:

  • 有意思,我不熟悉 DispatchGroup。让我探索一下。现在你的解决方案给了我 (Cannot invoke 'notify' with an argument list of type '(() -> ())') 错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
  • 1970-01-01
  • 2019-06-01
  • 1970-01-01
相关资源
最近更新 更多