(iOS)bomo doを使用したタイマアプリケーションの作成


機能の詳細

  • DatePickerタイマー時間を設定します.
  • スタートボタンを押してタイマーを開始し、一時停止ボタンを押してタイマーを一時停止します.
  • キャンセルボタンを押してタイマーを閉じます.
  • countdownが完了するとアラートが発行されます.
  • テクノロジーを活用

  • DispatchSourceTimer
  • UIViewAnimation
  • インプリメンテーション

  • タイマー実施時使用DispatchSourceTimer-タイマを作成する関数のパラメータ値の中でqueue部分的に.mainを宣言して、タイマがメインスレッドで回転するようにします.(UIの関連部分はすべてメインスレッドにあります.)
    -タイマがsuspendの場合nilを受け取ります.つまり、一時停止状態で「キャンセル」をクリックするとRuntime Errorが発生します.したがって、キャンセルする前に、タイマーの状態をresumeに設定する必要があります.
  • UIViewAnimationを使用して、タイマーの起動またはキャンセル時にスムーズな切り替えを行います.
    -また、タイマーが回転すると、ポモドも画像の回転を実現する.
  • import UIKit
    import AudioToolbox
    
    enum TimerStatus {
        case start
        case pause
        case end
    }
    
    class ViewController: UIViewController {
        @IBOutlet weak var timerLabel: UILabel!
        @IBOutlet weak var progressView: UIProgressView!
        @IBOutlet weak var datePicker: UIDatePicker!
        @IBOutlet weak var imageView: UIImageView!
        @IBOutlet weak var cancelButton: UIButton!
        @IBOutlet weak var toggleButton: UIButton!
        
        var duration = 60
        var timerStatus: TimerStatus = .end
        var timer: DispatchSourceTimer?
        var currentSeconds = 0
        
        override func viewDidLoad() {
            super.viewDidLoad()
            self.configureToggleButton()
        }
        
        func setTimerInfoViewVisible(isHidden: Bool) {
            self.timerLabel.isHidden = isHidden
            self.progressView.isHidden = isHidden
        }
        
        func configureToggleButton() {
            self.toggleButton.setTitle("시작", for: .normal)
            self.toggleButton.setTitle("일시정지", for: .selected)
        }
        
        func startTimer() {
            if self.timer == nil {
                self.timer = DispatchSource.makeTimerSource(flags: [], queue: .main)
                self.timer?.schedule(deadline: .now(), repeating: 1)
                self.timer?.setEventHandler(handler: { [weak self] in
                    guard let self = self else { return }
                    self.currentSeconds -= 1
                    let hour = self.currentSeconds / 3600
                    let minutes = (self.currentSeconds % 3600) / 60
                    let seconds = (self.currentSeconds % 3600) % 60
                    self.timerLabel.text = String(format: "%02d:%02d:%02d", hour, minutes, seconds)
                    self.progressView.progress = Float(self.currentSeconds) / Float(self.duration)
                    UIView.animate(withDuration: 0.5, delay: 0, animations: {
                        self.imageView.transform = CGAffineTransform(rotationAngle: .pi)
                    })
                    UIView.animate(withDuration: 0.5, delay: 0.5, animations: {
                        self.imageView.transform = CGAffineTransform(rotationAngle: .pi * 2)
                    })
                    
                    if self.currentSeconds <= 0 {
                        self.stopTimer()
                        AudioServicesPlaySystemSound(1005)
                    }
                })
                self.timer?.resume()
            }
        }
        
        func stopTimer() {
            if self.timerStatus == .pause {
                self.timer?.resume()
            }
            
            self.timerStatus = .end
            self.cancelButton.isEnabled = false
            UIView.animate(withDuration: 0.5, animations: {
                self.timerLabel.alpha = 0
                self.progressView.alpha = 0
                self.datePicker.alpha = 1
                self.imageView.transform = .identity
            })
            self.toggleButton.isSelected = false
            self.timer?.cancel()
            self.timer = nil
        }
        
        @IBAction func tapCancelButton(_ sender: UIButton) {
            switch self.timerStatus {
            case .start, .pause:
                self.stopTimer()
                
            default:
                break
            }
        }
        
        @IBAction func tapToggleButton(_ sender: UIButton) {
            self.duration = Int(self.datePicker.countDownDuration)
            
            switch self.timerStatus {
            case .end:
                self.currentSeconds = self.duration
                self.timerStatus = .start
                UIView.animate(withDuration: 0.5, animations: {
                    self.timerLabel.alpha = 1
                    self.progressView.alpha = 1
                    self.datePicker.alpha = 0
                })
                self.toggleButton.isSelected = true
                self.cancelButton.isEnabled = true
                self.startTimer()
                
            case .start:
                self.timerStatus = .pause
                self.toggleButton.isSelected = false
                self.timer?.suspend()
                
            case .pause:
                self.timerStatus = .start
                self.toggleButton.isSelected = true
                self.timer?.resume()
            }
        }
    }

    最終画面



    GitHub


    https://github.com/pjs0418/PomodoroTimer

    ソース


    快速キャンパス、超差コース:SWIFTを使用して30項目のiOSアプリケーションを開発