Swift - 使用NSTimer

时间:2015-07-15 18:29:02

标签: ios swift uiprogressview

所以我使用NSTimer让用户知道应用程序正在运行。进度条设置为持续3秒,但在运行时,它以“滴答”运动显示,并且它不应该像应该的那样平滑。无论如何,我可以让它更顺利 - 我确信我的计算错误......

如果有人能看一眼就会很棒。这是代码:

import UIKit

class LoadingScreen: UIViewController {


    var time : Float = 0.0
    var timer: NSTimer?

    @IBOutlet weak var progressView: UIProgressView!


    override func viewDidLoad() {
        super.viewDidLoad()

// Do stuff

timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector:Selector("setProgress"), userInfo: nil, repeats: true)

}//close viewDidLoad

  func setProgress() {
        time += 0.1
        progressView.progress = time / 3
        if time >= 3 {
            timer!.invalidate()
        }
    }

}

4 个答案:

答案 0 :(得分:19)

编辑:一个简单的3秒UIView动画(推荐)

如果你的酒吧只是平稳地移动以指示活动,可以考虑使用UIActivityIndicatorView或自定义UIView动画:

override func viewDidAppear(animated: Bool)
{
    super.viewDidAppear(animated)

    UIView.animateWithDuration(3, animations: { () -> Void in
        self.progressView.setProgress(1.0, animated: true)
    })
}

确保您的progressView的进度设置为零开始。这将导致3秒的平滑动画。

简单的动画进度(工作但仍然跳跃一点)

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIProgressView_Class/#//apple_ref/occ/instm/UIProgressView/setProgress:animated

func setProgress() {
    time += 0.1
    progressView.setProgress(time / 3, animated: true)
    if time >= 3 {
        timer!.invalidate()
    }
}

间隔较小的选项。 (不推荐)

将计时器设置为较小的间隔:

timer = NSTimer.scheduledTimerWithTimeInterval(0.001, target: self, selector:Selector("setProgress"), userInfo: nil, repeats: true)

然后更新你的功能

func setProgress() {
    time += 0.001
    progressView.setProgress(time / 3, animated: true)
    if time >= 3 {
        timer!.invalidate()
    }
}

答案 1 :(得分:2)

很难确切地说出问题所在。如果你在setProgress中打印一行打印时间戳,我想查看输出。它实际上每十分之一秒发射一次吗?我的猜测是不是。

为什么不呢?好吧,计时器在主线程中调度运行循环任务以执行setProgress中的代码。在队列中的任务执行之前,此任务无法运行。因此,如果您的主线程中发生了长时间运行的任务,您的计时器将非常不精确地触发。我的第一个建议是,这可能正在发生。

以下是一个例子:

  1. 你开始计时器每秒都做一些事情。
  2. 之后,您开始一个长时间运行的主线程任务(例如,您尝试将大量数据写入文件)。此任务将需要五秒钟才能完成。
  3. 你的计时器想要在一秒钟之后开火,但你的文件写入是 在接下来的四秒内占用主线程,因此定时器无法触发 再过四秒钟。
  4. 如果是这种情况,那么要解决问题,您需要将主线程工作移动到后台线程,或者在定期返回运行循环时找出一种方法。例如,在长时间运行的主线程操作期间,您可以定期在运行循环上调用runUntilDate以执行其他运行循环任务。

    请注意,您不能在长时间运行的主线程任务期间定期增加进度条填充,因为在您返回到运行循环之前,进度条实际上不会为其填充设置动画。

答案 2 :(得分:2)

动画更改的正确方法如何:animateWithDuration:animations:CABasicAnimation。您可以使用它来创建流畅的动画

答案 3 :(得分:1)

继续加载

timer = Timer.scheduledTimer(timeInterval: 0.001, target: self, selector: #selector(setProgress), userInfo: nil, repeats: true)

func setProgress() {
        time += 0.001
        downloadProgressBar.setProgress(time / 3, animated: true)
        if time >= 3 {
            self.time = 0.001
            downloadProgressBar.progress = 0
            let color = self.downloadProgressBar.progressTintColor
            self.downloadProgressBar.progressTintColor = self.downloadProgressBar.trackTintColor
            self.downloadProgressBar.trackTintColor = color
        }