質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

1回答

900閲覧

swiftでストップウォッチアプリを作りたい

swift

総合スコア0

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/10/08 11:51

前提・実現したいこと

アップル純正のストップウォッチアプリを作りたいのです。

発生している問題・エラーメッセージ

開始ボタンを押した後に停止ボタンを押し、その後、開始ボタンを押すと停止させた時間分進んで表示されてしまいます。

該当のソースコード

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var minuteLabel: UILabel! @IBOutlet weak var secondLabel: UILabel! @IBOutlet weak var subsecondLabel: UILabel! @IBOutlet weak var lapButton: UIButton! @IBOutlet weak var startAndStopButton: UIButton! @IBOutlet weak var tableView: UITableView! fileprivate var timer: Timer? fileprivate var startTime = Date() private var isWorkingTimer = false private var isPaused = false override func viewDidLoad() { super.viewDidLoad() subsecondLabel.text = "00" secondLabel.text = "00" minuteLabel.text = "00" startAndStopButton.backgroundColor = .green } @IBAction func startAndStopButton(_ sender: Any) { if !isWorkingTimer && !isPaused { timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(startButtonAction), userInfo: nil, repeats: true) startTime = Date() startAndStopButton.backgroundColor = .red startAndStopButton.setTitle("停止", for: .normal) //ラップボタンを使えるようにする isWorkingTimer = true }else if isWorkingTimer && !isPaused { timer?.invalidate() startAndStopButton.backgroundColor = .green startAndStopButton.setTitle("開始", for: .normal) //ラップボタンをリセット表示にする isPaused = true }else if isWorkingTimer && isPaused { timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(startButtonAction), userInfo: nil, repeats: true) startAndStopButton.backgroundColor = .red startAndStopButton.setTitle("停止", for: .normal) //リセットボタンをラップ表示にする isPaused = false } } @objc func startButtonAction(_ sender: Any) { let currentTime = Date().timeIntervalSince(startTime) let subsecond = Int((currentTime - floor(currentTime))*100) let second = Int(fmod(currentTime, 60)) let minute = Int(fmod((currentTime/60), 60)) subsecondLabel.text = String(format:"%02d", subsecond) secondLabel.text = String(format:"%02d", second) minuteLabel.text = String(format:"%02d", minute) }

}

試したこと

どうすればいいのか見当がつきませんでした。

補足情報(FW/ツールのバージョンなど)

swift,xcode共に最新です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TsukubaDepot

2020/10/08 12:29

次回ご質問される時には、コード部分を ``` で囲むか、あるいは <code> 機能を使ってコードを掲載していただけますでしょうか。 回答のように、整形された読みやすい表示になりますので、ぜひご協力お願いします。
guest

回答1

0

ストップウォッチを作るだけなら、Date型を使う必要は一切ありません。

逆に、時刻の管理を Date().timeIntervalSince(startTime) を使って行なっているため、中断時間も加味される結果となってしまっています。

Timer0.01秒ごとの割り込みを使っているわけですから、率直に割り込みごとに 0.01 秒増やして計算させた方が考えるのが楽かと思います。

あるいは、再開させた時にあらためて

Swift

1 startTime = Date()

させる方法もあります。

Swift

1import UIKit 2 3class ViewController: UIViewController { 4 5 @IBOutlet weak var minuteLabel: UILabel! 6 @IBOutlet weak var secondLabel: UILabel! 7 @IBOutlet weak var subsecondLabel: UILabel! 8 @IBOutlet weak var startAndStopButton: UIButton! 9 fileprivate var timer: Timer? 10 // MARK: - 開始ボタンを押されてからの時間を Double で記録する 11 fileprivate var startTime = 0.0 12 13 private var isWorkingTimer = false 14 private var isPaused = false 15 16 override func viewDidLoad() { 17 super.viewDidLoad() 18 subsecondLabel.text = "00" 19 secondLabel.text = "00" 20 minuteLabel.text = "00" 21 startAndStopButton.backgroundColor = .green 22 23 } 24 25 @IBAction func startAndStopButton(_ sender: Any) { 26 if !isWorkingTimer && !isPaused { 27 timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(startButtonAction), userInfo: nil, repeats: true) 28 // MARK: - 「開始」ボタンが押された瞬間を基準とする 29 startTime = 0.0 30 startAndStopButton.backgroundColor = .red 31 startAndStopButton.setTitle("停止", for: .normal) 32 //ラップボタンを使えるようにする 33 isWorkingTimer = true 34 }else if isWorkingTimer && !isPaused { 35 timer?.invalidate() 36 startAndStopButton.backgroundColor = .green 37 startAndStopButton.setTitle("開始", for: .normal) 38 //ラップボタンをリセット表示にする 39 isPaused = true 40 } 41 // TODO: ラップボタンは今は忘れる 42 } 43 44 // MARK: - 「開始」ボタンを押された時の時間を起点として計算させるだけ 45 @objc func startButtonAction(_ sender: Any) { 46 // 0.01秒増やす(TImer の timeInterval と同じ値にする 47 startTime += 0.01 48 49 // 100倍した値を100で割ったあまり 50 let subsecond = Int(startTime * 100) % 100 51 // 60の剰余 52 let second = Int(startTime) % 60 53 // startTime を 60 で割った値を 60 で割ったあまり 54 let minute = Int(startTime / 60) % 60 55 56 subsecondLabel.text = String(format:"%02d", subsecond) 57 secondLabel.text = String(format:"%02d", second) 58 minuteLabel.text = String(format:"%02d", minute) 59 } 60}

投稿2020/10/08 12:28

TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問