AppDelegate内にViewControllerのメソッドを呼び出したい
2018-03-19
氷翠です。
タイトルの通り、今回の目的はこちら。
で、要は、AppDelegate内でプログラムを記述していき、出力的なものはViewControllerなのだから、その中にあるメソッドを利用することはできないのだろうか?
という疑問です。
完成品はこちら。
メニューバーにある、とある項目を選択した場合、上の画像の様にテキストフィールドにそのタイトルが出て来るというもの。
メニューを選択した場合の処理自体は「AppDelegate」の中でメソッドを作りました。
しかし、そのまま出力しようとすると、このテキストフィールド自体はnilの状態になる。
かといって、Storyboardでつなげようとしてもつながりません。
ということは、このAppDelegateのクラスのメソッドの中でViewControllerのメソッドを利用することができれば、出力されるのではないだろうかと考えました。
@IBAction func menu(_ s: NSMenuItem) { }
まず、「AppDelegate」内でメニューが選択されたら動き始めるこんなメソッドを用意し、特定のメニューに対してStroeyBoardでつなげてあげます。
こんな感じになるはず。これはStoryBoard上、メインメニューの項目を選択した状態になります。
で、これはメインメニューのところに表示されている「AppDelegate」のオブジェクトを選択した状態になります。
こんな感じでつなげてあげればメニューを選択したときの処理を行うことができるかと思います。
また、テキストフィールに対しては「ViewController」に繋いでおきます。
次にAppDelegateからViewControllerを呼び出すため、準備するのは、
import Cocoa class ViewController: NSViewController { @IBOutlet weak var tf: NSTextField! override func viewDidLoad() { super.viewDidLoad() let appDelegate:AppDelegate = NSApplication.shared.delegate as! AppDelegate appDelegate.viewController = self // Do any additional setup after loading the view. } override var representedObject: Any? { didSet { // Update the view, if already loaded. } } }
「ViewController」の中身です。
5行目辺りでテキストフィールドの宣言をしているのがわかります。
で、問題は「override func viewDidLoad()」の中身です。
「super.viewDidLoad()」の後に、2行程追加していますが、これが重要。
さらに、「AppDelegate」の方は、、、
import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { var viewController: ViewController! func applicationDidFinishLaunching(_ aNotification: Notification) { // Insert code here to initialize your application } func applicationWillTerminate(_ aNotification: Notification) { // Insert code here to tear down your application } @IBAction func menu(_ s: NSMenuItem) { viewController.tf.stringValue = "「" + s.title + "」が選択されました" } }
共通で使うため、「viewController」という変数を宣言。で、最初に作ったメニューが選択されたときの処理の部分を見ます。
この「viewController」の中にパラメータとして、「ViewController」クラスの中で定義していたテキストフィールドの変数「tf」が使えるように呼び出されています。で、その「tf」のパラメータ「stringValue」に文字列を代入すれば表示されるので、代入してあげます。
これで最初の画像のような結果になるわけです。
また、メニューの項目をこの「menu」に繋いであげれば、他の項目名も対応することができます。
コメントを残す