昨日はゲーム画面からスタート画面への遷移を作った。
今日は遷移するときに確認のダイアログを出すようにしていく。
UIAlertController
確認のダイアログを出すときに使えるのが、UIAlertController。
(なお、以前はUIAlertViewが使われていたけれど、非推奨(Deprecated)になっているので、使わない方がいい)
UIAlertControllerでは2種類のビューのスタイルが利用できて、一つはアクションシート(ActionSheet)、もう一つはアラート(Alert)。
ダイアログを出したい場合、後者を使うといい。
確認ダイアログの表示
ということで、さっそく実装。
//============================== // YWF //------------------------------ // GameScene.swift //============================== import SpriteKit public class GameScene: SKScene, ButtonNodeObserver { // 省略 public func buttonIsSelected(button: ButtonNode) { let dialog = UIAlertController(title: nil, message: "Do you really want to leave this game?", preferredStyle: .Alert) dialog.addAction(UIAlertAction(title: "Yes", style: .Default, handler: { (action:UIAlertAction!) -> Void in let scene = StartScene(size: self.size) let transition = SKTransition.fadeWithDuration(NSTimeInterval(1.0)) self.view?.presentScene(scene, transition: transition) })) dialog.addAction(UIAlertAction(title: "No", style: .Cancel, handler: nil)) self.view?.window?.rootViewController?.presentViewController(dialog, animated: true, completion: nil) } // 省略 }
まず、UIAlertControllerのインスタンスを作成。
スタイルは前述した通り、アラート。
そして、そこにアクション(UIAlertAction)を追加していく。
ボタンが押されたときの処理はクロージャで記述する。
最後に、作成したダイアログの表示。
UIAlertControllerはUIViewControllerを継承しているので、UIViewController#presentViewController(_: UIViewController, animated: Bool, completion: (() -> Void)?)の引数に指定してダイアログを表示させる。
じゃあ、レシーバのUIViewControllerは何にすればいいのかというと、ダイアログを表示させようとしているビューコントローラ・・・なわけだけど、SpriteKitを使っている場合、ちょっと困ってしまう。
というのも、SpriteKitの場合、ビューコントローラとビューという関係は、ビューの中のシーンとノードという関係になっているので、ビューコントローラはビューの内側のシーンやノードにはノータッチで、それゆえ、シーンやノードも自身を表示させている大元のビューコントローラを知ることが出来ないから。
一つの方法としては、ビューコントローラから最初のシーンを作るときに、ビューコントローラへの参照をシーンに渡しておいて、非所有参照でそれを保持しておくということが考えられる。(非所有参照(あるいは弱い参照)にしておかないと、参照がループするので注意)
ただ、それだと辻褄を無理やり合わせている感じがして、ちょっと微妙。
もう一つの方法は、自分がやった方法。
これもかなり無理やりな感じだけど、つまり、現在のウィンドウの根っこのビューコントローラに表示させるという方法。
まぁ、ダイアログがモーダルであることを考えると、ウィンドウ自体にダイアログを表示させるという考え方は、それほど間違いではないはず。
動作確認
さて、これで実際に動かしてみると、ちゃんと確認ダイアログが表示されて、"No"をクリックしたときには何も起きず、"Yes"をクリックしたときにだけスタート画面に戻っているのが分かると思う。
今日はここまで!