姓名診断アプリ

#仕様
・名前を入力すると画面遷移し、その人のスコアが表示される(100までの乱数)
・名前が未入力の場合エラーメッセージのポップが表示される

#学び

##画面遷移

###Navigation Controller作成
上のメニューにある`Edior`→`Embed In`→`Navigation Controller`を押すと
新規画面（`Navigation Controller`）が作成される。
ここに名前を入力とsendボタンを作成する

###View Controller作成→後の(ResultView Controller)

この`View Controller`にはクラスがないので`ResultView Controller`という名前で新規ファイルを作成。
`Main.storybord`の`ResultView Controller`とつなげるために黄色い丸のアイコンを押して`ResultView Controller`を指定

###segue
`Navigation Controller`から`ResultView Controller`に画面遷移するように`segue`を設定する
`segue`を設定することでこのアクションが起こったときに遷移する画面を決めることができる
`segue`に名前をつけて(`identifier`)プログラムで識別できるようにしなきゃいけない(今回は`showResult`)


##prepareメソッド
`prepare`はsegueが動作することをViewControllerに通知するメソッド

```swift

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let resultVC = segue.destination as! ResultViewController
        resultVC.myName = self.nameText.text!
       #遷移先のコントローラ.変数 = このコントローラのtexrField煮付けた変数.text!←アンラップ
    }
```

`func prepare(for segue: UIStoryboardSegue, sender: Any?)`
「遷移するから準備してね」という関数らしい。


`segue.destination` 
遷移先の画面を取ることができます。(destination→目的地の取得)


`as!`
型変換で強制ダウンキャストをしている。
[アップキャストとダウンキャスト](https://qiita.com/suisuina/items/f8639d1aee61fb0530b5)

参考：https://ema-hiro.hatenablog.com/entry/20170304/1488618103


そして、もしsegueがたくさんあった時に、ちゃんと指定したsegue(identifierに設定した名前)に反応させるために条件分岐をする
[guard let と if letの違い](https://qiita.com/solty_919/items/8b22c8b30cd1a5596c83)

##画面遷移時の判定処理

```swift
  override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    if identifier == "showResult" {
    guard self.nameText.text != "" else {
      let alertController = UIAlertController(title: "Error", message: "入力して！", preferredStyle: .alert)
      let defaultAction = UIAlertAction(title: "ok", style: .
        default, handler: nil)
      alertController.addAction(defaultAction)
      self.present(alertController, animated: true, completion: nil)
      return false
      }
        return true
      }
       return true
  }
```

`shouldPerformSegue`
画面遷移判定用のメソッドで、falseを戻すと画面遷移をキャンセルする

参考：https://qiita.com/masch/items/15e648a48351b8377439

`let alertController = UIAlertController(title: "Error", message: "入力して！", preferredStyle: .alert)`
 UIAlertControllerクラスのインスタンスを生成
 タイトル, メッセージ, Alertのスタイルを指定する


`let defaultAction = UIAlertAction(title: "ok", style: .default, handler: nil)`
Action初期化時にタイトル, スタイル, 押された時に実行されるハンドラを指定する
ハンドラ→これを押した時に何かの処理をするか(今回は OK ボタンを押しても何もしないので nil )

参考:https://qiita.com/funafuna/items/b76e62eb82fc8d788da5

`self.present(alertController, animated: true, completion: nil)`

構文: `present(_:animated:completion:)`
`present`は表示するメソッド
`animated は true` 
`completion: nil `終わった後の処理がないのでnil


##viewWillAppear
```swift

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        self.nameText.text = ""
    }
```

構文: `viewWillAppear(_:)`

`viewWillAppear`はviewが表示される直前に呼ばれるメソッド


※`viewDidAppear`っていうメソッドもある。これは完全に遷移が行われ、スクリーン上に表示された時に呼ばれる。

参照：https://qiita.com/motokiee/items/0ca628b4cc74c8c5599d



##キーボードを閉じる
```swift
self.nameText.resignFirstResponder()
```
これを`prepare`メソッドの一番下に書けば画面遷移する前にキーボードが消える


##キーボードのsendボタンを押して画面遷移する

###delegade
あるクラスの処理の実装を別のクラスに任せるための仕組み
`UITextFieldDeligate`と`UITextField`と`ViewController`が必要
sendボタンを押すと`UITextFieldDeligate`から`UITextField`に処理依頼がいくが、`UITextField`は実際の処理をしているんではなく、`ViewController`に向かって処理きてるよー頼んだーって感じ。
`ViewController`は真面目なのでちゃんと処理を行って`UITextField`に任務完了しましたーっていうながれ。

なので

```swift
class ViewController: UIViewController, UITextFieldDelegate {
```
`UITextField`には`UITextFieldDeligate`というプロトコルがあるので、そちらを`ViewController` に適合させる


####viewDidload内にtextFieldの情報を受け取るための delegate を設定
```ViewController.swift

textField.delegate = self #(自分自身)
```
textFieldのdelegateに対しselfをセットし忘れると`textFieldShouldReturn`が呼ばれません。

sendボタンを`ResultController`に接続させ、 `sendButton`と名付け、処理を書く

```ViewController.swift

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.sendButton.sendActions(for: .touchUpInside)
        return true
    }
```
`textFieldShouldReturn`というメソッドを使ってボタンタップ時にキーボードを閉じる指令を出す