秒表 - 停止并开始

时间:2017-07-11 17:35:23

标签: swift stopwatch

我正在制作一个简单的秒表。 我面临的问题是当我再次开始时,我开始/恢复秒表。 我试图保持经过时间的价值,但没有运气

demo = enter image description here

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource  {

    var timer:Timer = Timer()
    var time:Int = 0
    var isActive: Bool = false
    var isReset: Bool = true
    var startTime:TimeInterval?
    var elapsed:TimeInterval?

    var timeInterval:TimeInterval?

    var laps:[String] = [String]()
    var timerDefaults = UserDefaults.standard

    @IBOutlet weak var lapTableView: UITableView!
    @IBOutlet weak var stopwatchLabel: UILabel!
    @IBOutlet weak var labButton: UIButton!
    @IBOutlet weak var startButton: UIButton!



    @IBAction func addLapAction(_ sender: Any) {

        if isActive {
            addLapToTableView()
        } else {
            resetTimer()
        }
    }



    @IBAction func startWatchButton(_ sender: Any) {

        if isActive {
          stopTimer()
        } else {
          startTimer()
        }

    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib
        configureTableView()

        startTime = Date.timeIntervalSinceReferenceDate

    }

    func configureTableView() {
        lapTableView.delegate = self
        lapTableView.dataSource = self
    }

    //start timer
    func startTimer() {
         timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(ViewController.incrementTimer), userInfo: nil, repeats: true)

        isActive = true

        startButton.setTitle("Stop", for: .normal)
        startButton.backgroundColor = UIColor.red

        labButton.setTitle("Lap", for: .normal)

    }

    func funcTimer() {

        timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(ViewController.incrementTimer), userInfo: nil, repeats: true)
    }

    //stop timer
    func stopTimer() {

        isActive = false
        isReset = false


        timer.invalidate()

        startButton.setTitle("Start", for: .normal)
        startButton.backgroundColor = UIColor.green

        labButton.setTitle("Reset", for: .normal)
    }

    //reset timer
    func resetTimer() {

        isActive = false
        isReset = true

        laps = []
        lapTableView.reloadData()
        stopwatchLabel.text = "00:00:00"
    }

    func incrementTimer() {
        time += 1

        if isReset {
            stopwatchLabel.text = newTime()
        } else {
           stopwatchLabel.text = updateTime()
        }

    }


    //add lap to tableView
    func addLapToTableView() {
        laps.append(stopwatchLabel.text!)
        lapTableView.reloadData()
        print("current lap : \(stopwatchLabel.text!)")
    }


    func displayMinSeconds(time:Int) -> String {

        let minutes:Int = time / 60 % 60
        let seconds:Int = time % 60
        let milliseconds:Int = time * 1000

        return String(format: "%02i:%02i:%02i",  minutes, seconds, milliseconds)
    }


    func newTime() -> String  {
        let currentTime = Date.timeIntervalSinceReferenceDate
        let elapsedTime: TimeInterval = currentTime - startTime!
        return updateTimer(time: elapsedTime)
    }

    func updateTime() -> String {

        return updateTimer(time: elapsed!)
    }

    func updateTimer(time:TimeInterval) -> String {
        var elapsedTime = time

        //calculate the minutes in elapsed time.

        let minutes = UInt8(elapsedTime  / 60.0)
        elapsedTime  -= (TimeInterval(minutes) * 60)

        //calculate the seconds in elapsed time.

        let seconds = UInt8(elapsedTime )

        elapsedTime  -= TimeInterval(seconds)

        //find out the fraction of milliseconds to be displayed.

        let fraction = UInt8(elapsedTime  * 100)

        //add the leading zero for minutes, seconds and millseconds and store them as string constants


        //concatenate minuets, seconds and milliseconds as assign it to the UILabel

        elapsed = elapsedTime
        return String(format: "%02d:%02d:%02d",  minutes, seconds, fraction)

    }



    //MARK - Table View Data Source
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return laps.count
    }


    @objc(tableView:cellForRowAtIndexPath:) func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "lapCell", for: indexPath)


         cell.textLabel?.text = "lap \(indexPath.row + 1)"

        if indexPath.row == 0 {
            cell.detailTextLabel?.text = ""
        } else {
            cell.detailTextLabel?.text = laps[indexPath.row]
        }



        cell.textLabel?.textColor = UIColor.white
        cell.detailTextLabel?.textColor = UIColor.white

        return cell

    }
}

1 个答案:

答案 0 :(得分:0)

你在这里做的是使用增量变量来显示时间,使用Date()引用来计算差异。这是非常棘手的,并且在我告诉你坚持使用这两种方法之前构建了一些计时器应用程序要好于采用两种方式。

我强烈推荐的方法是增量变量,每0.01秒运行一次计时器(因为它是你显示的最高小数点),你的时间变量是经过了多少0.01秒。这样,当你停止/恢复时,你只是重新添加到该值,显示经过的时间变成一个简单的数学问题,同时以分钟/秒/小时等访问该时间。 就个人而言,我更喜欢这种方法而不是使用Date(),因为你可以更自由地显示信息,你不需要依赖于Date()属性的属性类型转换,无论哪种方式,对于简单的用例,你将不得不即使您使用Date(),也可以在某处存储数字类型的值。因此,对于更简单的计时器应用程序,您可能根本不打算使用Date()。

日期似乎更有用的唯一时间是,当您需要持久性(保存在文件或数据库中)时。就像你想要一个可以被解雇的计时器,并在你离开的地方带回来的时候,当你在监视位置数据所花费的时间,以及你想要时间数据以后可能用于活动分析或用户趋势时等

我能想到的使用Date的最简单的情况是使用Date的timeIntervalSince1970属性。当你暂停时它也不会计算东西,节省电池消耗就像增量方法一样。您仍需要一个时间增量变量来跟踪记录所花费的时间,另一个变量用于跟踪暂停时间,但如果您尝试同时使用这两个数字和日期

,它会有所帮助
var start = Date()
var stopped : Date?
var resumed : Date?
var finished : Date?

var timer : Timer?

var timeElapsed = Double()
var timeStopped = Double()

var actualTimeElapsedInMilliseconds : Int {
    get {
        return Int(timeElapsed - timeStopped)
    }
}

var actualTimeElapsedInTenthOfSecond : Int {
    get {
        return Int((timeElapsed - timeStopped) / 10.0)
    }
}

var actualTimeElapsedInSeconds : Int {
    get {
        return Int((timeElapsed - timeStopped) / 1000)
    }
}


func startTimer() {

    start = Date()
    timer = Timer.init(timeInterval: 0.01, repeats: true, block: { (this) in
        performActiveTimer()
    })

}

func reStartTimer() {

    resumed = Date()
    if let stop = stopped, let resume = resumed {
        timeStopped = timeStopped + (resume.timeIntervalSince1970 - stop.timeIntervalSince1970)
    }
    timer = Timer.init(timeInterval: 0.01, repeats: true, block: { (this) in
        performActiveTimer()
    })

}

func pause() {
    timer?.invalidate()
    stopped = Date()
}

func performActiveTimer() {
    timeElapsed = Date().timeIntervalSince1970 - start.timeIntervalSince1970
    //here i would call you UI update method
}

func terminateTimerAndSave() {
    let now = Date()
    finished = now
    timeElapsed = now.timeIntervalSince1970 - start.timeIntervalSince1970
}

如前所述,使用增量器需要较少的代码,但这种混合方法是执行计时器的最简单方法。顺便说一下,这只是逻辑,你需要使用显示的计算变量来显示你想要的时间。您还需要确保正确替换方法。以避免不正确地覆盖可选日期。