解放区在住氷翠 緑の閃光
【解放区在住氷翠】氷翠のお気楽日記

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」に繋いであげれば、他の項目名も対応することができます。

コメントを残す

メールアドレスが公開されることはありません。