XCode6 では、iOS と同様、OSX でも Storybord がデフォルトで採用されるようになった。
ヒレガス本のサンプルを Swift で写経するのが、ちょっと行き詰っている(Storybord を利用した場合の、Documentbased Application の作成方法がさっぱり判らない)ので、気分転換に、そもそも Storybord はどうやって使うのかと、YouTube に公開されている OSX での Storybord を用いたアプリケーション開発の簡単なチュートルアルを勉強として写経してみた。
Using Storyboards for OS X - YouTube
ビデオでは、XCode6 のβ版を利用しており、追加した ViewController の init メソッドを修正しているが、現在配布されている XCode6.1 では修正する必要がなかった。それ以外は特に問題なく、ビデオの指示に従うだけで良かった。
ビデオを見ると一目瞭然だが、Storybord を利用した画面遷移の方法は、
- Storybord 上に View を追加する。
- 追加した View に対応する NSViewController の派生クラスを作成し、追加した View の Identity Inspector の Custom Class セクションの Class 欄に作成した NSViewController の派生クラスを指定する。
- 画面遷移の契機となるコントロールから対象となる View まで Control キーを押下しながらドラッグし、セグウェイで接続する。
この時、画面遷移のスタイルとして、Show(モーダレスダイアログ), Modal(モーダルダイアログ), Sheet(シートダイアログ), Popover(ポップアップウィンドウ), Custom を選択することができる。
で行うことができる。
View 間での値の受け渡しは、今回のチュートリアルでは NSViewController に用意された representedObject プロパティを介して行っている。親となる ViewController のセグウェイでの画面遷移直前にコールされる prepareForSegue メソッドで、子となる ViewController の representedObject に値をセット、子となる ViewController ではオブジェクトがメモリにロード後にコールされる viewWillAppear メソッドで値を受けっている。最初、このチュートリアルを見て、prepareForSegue メソッド内で遷移先の ViewController の参照を取得しているのだから、直接アウトレットにアクセスすれば良いんじゃね?と思って試してみたが、この時点ではまだ View との接続が完了しておらず、アウトレット経由で View 上のコントロールにアクセスすることはできなかった。
遷移した View を閉じるのは、ViewController のメソッド dismissController に自分自身を引数に渡して呼び出せば良いようだ。(セグウェイのスタイルで Show を選択した場合は、この方法ではうまくいかない。)
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.
}
}
}
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.
}
}