仕様
・名前を入力すると画面遷移し、その人のスコアが表示される(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に通知するメソッド
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://ema-hiro.hatenablog.com/entry/20170304/1488618103
そして、もしsegueがたくさんあった時に、ちゃんと指定したsegue(identifierに設定した名前)に反応させるために条件分岐をする
guard let と if letの違い
画面遷移時の判定処理
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
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.nameText.text = ""
}
構文: viewWillAppear(_:)
viewWillAppear
はviewが表示される直前に呼ばれるメソッド
※viewDidAppear
っていうメソッドもある。これは完全に遷移が行われ、スクリーン上に表示された時に呼ばれる。
参照:https://qiita.com/motokiee/items/0ca628b4cc74c8c5599d
キーボードを閉じる
self.nameText.resignFirstResponder()
これをprepare
メソッドの一番下に書けば画面遷移する前にキーボードが消える
キーボードのsendボタンを押して画面遷移する
delegade
あるクラスの処理の実装を別のクラスに任せるための仕組み
UITextFieldDeligate
とUITextField
とViewController
が必要
sendボタンを押すとUITextFieldDeligate
からUITextField
に処理依頼がいくが、UITextField
は実際の処理をしているんではなく、ViewController
に向かって処理きてるよー頼んだーって感じ。
ViewController
は真面目なのでちゃんと処理を行ってUITextField
に任務完了しましたーっていうながれ。
なので
class ViewController: UIViewController, UITextFieldDelegate {
UITextField
にはUITextFieldDeligate
というプロトコルがあるので、そちらをViewController
に適合させる
viewDidload内にtextFieldの情報を受け取るための delegate を設定
textField.delegate = self #(自分自身)
textFieldのdelegateに対しselfをセットし忘れるとtextFieldShouldReturn
が呼ばれません。
sendボタンをResultController
に接続させ、 sendButton
と名付け、処理を書く
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.sendButton.sendActions(for: .touchUpInside)
return true
}
textFieldShouldReturn
というメソッドを使ってボタンタップ時にキーボードを閉じる指令を出す