カウントダウンアプリ

#仕様
時間を設定(別画面)
設定した時間からタイマーが動きカウントダウンする
ストップボタンで時間一時停止
スタートボタンで開始/再開

#学び

##Timerクラス
タイマーで使用するクラス
指定した時間に何らかの処理を行えたり、定期的に繰り返しすることができる

```swift
var timer:Timer?　#タイマーの変数
var count = 0　　#経過時間を記録する変数
let setting_key = "timer_value"  #秒数を保持する時に利用するキーを作成
 ```

##UserDefaults
アプリで利用していた値を保存することができる(データの永続化)
データを取り出したり、書き換えたりすることができる
UserDefaultsに保存されている値はアプリの中で使いまわせる
アプリの起動時にキーと値のペアを永続的に保存します。(簡単に使えるキーバリュー型のDBみたいなもの)
キーと値のペアを簡単に永続化できるため、ちょっとした設定の保存などに向いています。



参考: http://programming-beginner-memo.com/?p=83

```swift
let settings = UserDefaults.standerd
#UserDefaultsを参照していて、この方法でインスタンスを生成する
settings.register(defaults: [settingKey: 10])
#UserDefaultsの初期値設定。今回は10秒スタートだよと。
```
`.register[]`


###画面を更新

更新するメソッドを作る

```swift
  func displayUpdate() -> Int {
    let settings = UserDefaults.standard
    let timerValue = settings.integer(forKey: settingKey)
    #settingKeyには初期値である10が入る状態
    let remainCount = timerValue - count
    timerLabel.text = "残り(\remainCount)秒"
    return remainCount
  }
```
経過時間を処理するメソッドを作る

```swift
  func timerInterrupt(_ timer:Timer){
    count += 1 #経過時間
    if displayUpdate() <= 0 {
      count = 0　#リセット
      timer.invalidate()　#タイマー止める
    }
  }
```

###カウントダウンの処理を作る

スタートボタンを押したとき
タイマーが実行中であれば何もなし

```swift

  @IBAction func startButton(_ sender: Any) {
    if let nowTimer = timer {
      if nowTimer.isValid == true {
        return
      }
    
    timer = Timer.scheduledTimer(timeInterval: 1.0,
                                 target: self,
                                 selector: #selector(self.timerInterrupt(_:)),
                                 userInfo: nil,
                                 repeats: true)
    }
  }
```
`.scheduledTimer`

selectorに入れる経過時間を処理するメソッドを作る


```swift

    @objc func timerInterrupt(_ timer:Timer){
    count += 1
    if displayUpdate() <= 0 {
      count = 0
      timer.invalidate()
      
      let alertController = UIAlertController(title: "終了", message: "タイマー終了時間です", preferredStyle: .alert)
      let alertAction = UIAlertAction(title: "OK", style: .default, handler: nil)
      alertController.addAction(alertAction)
      present(alertController, animated: true, completion: nil)
      
    }
  }
```

ストップボタンを押したとき
タイマーぶあれば`.inValidate()`で停止

```swift

  @IBAction func stopButton(_ sender: Any) {
    if let nowTimer = timer {
      if nowTimer.isValid == true {
        nowTimer.invalidate()
      }
    }
  }
```

時間設定をする際にも`ストップボタンを押した時と同じメソッド`　＋　`performSegue`で画面の遷移先を明示する

##viewDidAppear
時間設定してタイマー画面に戻ってきた際に動くメソッド
経過秒数を0にして、タイマーの表示時間を呼ぶ

```swift

  override func viewDidAppear(_ animated: Bool) {
    count = 0
    _ = displayUpdate()
  }
```

利用しない変数を定義すると警告が出るので `_`に代入している




##PickerViewを利用して値を入れる
`UIPickerViewDelegate`, `UIPickerViewDataSource`を追加して利用できるようにする


###PickerViewの列数指定

```swift

  func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
  }
```

###PickerViewの行数指定

```swift
  func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return settingArray.count
  }
```

###a
```swift

  func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return String(settingArray[row])
  }
  
  func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    let settings = UserDefaults.standard
    settings.set( settingArray[row], forKey: settingKey) // Keyを指定して保存
    settings.synchronize() // 別コントローラでの同期・永続化
  }
  
```

##一つ前の画面に戻る
魔法

 ```swift
navigationController?.popViewController(animated: true)
```
参考: https://capibara1969.com/203/#toc4