More than 1 year has passed since last update.

XCode6 では、iOS と同様、OSX でも Storybord がデフォルトで採用されるようになった。

ヒレガス本のサンプルを Swift で写経するのが、ちょっと行き詰っている(Storybord を利用した場合の、Documentbased Application の作成方法がさっぱり判らない)ので、気分転換に、そもそも Storybord はどうやって使うのかと、YouTube に公開されている OSX での Storybord を用いたアプリケーション開発の簡単なチュートルアルを勉強として写経してみた。

Using Storyboards for OS X - YouTube

ビデオでは、XCode6 のβ版を利用しており、追加した ViewController の init メソッドを修正しているが、現在配布されている XCode6.1 では修正する必要がなかった。それ以外は特に問題なく、ビデオの指示に従うだけで良かった。

ビデオを見ると一目瞭然だが、Storybord を利用した画面遷移の方法は、

  1. Storybord 上に View を追加する。
  2. 追加した View に対応する NSViewController の派生クラスを作成し、追加した View の Identity Inspector の Custom Class セクションの Class 欄に作成した NSViewController の派生クラスを指定する。
  3. 画面遷移の契機となるコントロールから対象となる View まで Control キーを押下しながらドラッグし、セグウェイで接続する。 この時、画面遷移のスタイルとして、Show(モーダレスダイアログ), Modal(モーダルダイアログ), Sheet(シートダイアログ), Popover(ポップアップウィンドウ), Custom を選択することができる。

で行うことができる。

View 間での値の受け渡しは、今回のチュートリアルでは NSViewController に用意された representedObject プロパティを介して行っている。親となる ViewController のセグウェイでの画面遷移直前にコールされる prepareForSegue メソッドで、子となる ViewController の representedObject に値をセット、子となる ViewController ではオブジェクトがメモリにロード後にコールされる viewWillAppear メソッドで値を受けっている。最初、このチュートリアルを見て、prepareForSegue メソッド内で遷移先の ViewController の参照を取得しているのだから、直接アウトレットにアクセスすれば良いんじゃね?と思って試してみたが、この時点ではまだ View との接続が完了しておらず、アウトレット経由で View 上のコントロールにアクセスすることはできなかった。

遷移した View を閉じるのは、ViewController のメソッド dismissController に自分自身を引数に渡して呼び出せば良いようだ。(セグウェイのスタイルで Show を選択した場合は、この方法ではうまくいかない。)

サンプルソース

ViewController.swift
import Cocoa

class ViewController: NSViewController {

    // NSColorWellへのアウトレット
    @IBOutlet weak var well: NSColorWell!

    // セグウェイでの画面遷移の直前に呼ばれる
    override func prepareForSegue(segue: NSStoryboardSegue, sender: AnyObject?) {
        // SecondControllerのインスタンスを取得する
        let subController = segue.destinationController as SecondController
        // NSColorWellで指定されたNSColorをSecondControllerへ引き渡す
        subController.representedObject = well.color
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    }
}
SecondController
import Cocoa

class SecondController: NSViewController {

    // NSBoxへのアウトレット
    @IBOutlet weak var box: NSBox!

    // ボタンクリックに対するアクション
    @IBAction func dismiss(sender: AnyObject) {
        self.dismissController(self)
    }

    // ViewControllerがメモリにロードされた後に呼び出される
    override func viewWillAppear() {
        // ViewController::prepareForSegueで設定したNSColorを取り出す
        let  color = self.representedObject as NSColor
        // NSBoxのfillColor属性に設定する
        box.fillColor = color
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
    }
}
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.