PlaygroundでStoryboardの試作

Swiftでロジックを組み立てるのにPlaygroundは便利だが、UIに関してはいまいち使いにくかった。

色々と調べたら、UIに関しても、Playgroundでプレビューするする方法が分かった。

要約すると以下のようになる。

  1. playground側でフレームワークを “import” すると、そのフレームワークが使える
  2. テストしたいクラスやリソースを含めたフレームワークを作る
  3. アプリケーションのソースコード中でplaygorundeで実行したいものは片っ端から、上記のフレームワークに入れる。
  4. フレームワークをビルドしてから、playgroudで使えるようになる
  5. 上記の、アプリのプリジェクト、フレームワークのプロジェクト、プレイグラウンドをまとめるために、ワークスペースを作り、上記の3つをその中に入れる。
  6. バンドルの指定が、メインバンドルでないことを気をつければふつーに使える。
../../../_images/PGWS01.png

準備

Playgroundとアプリケーションプロジェクトではお互いにソースファイルの共有がうまくゆかない。

シンボリックリンクやエリアスなども試したが、Xcodeの誤作動が多かった。

その上、Playgroundのリソースフォルダの中ではxibのコンパイルも自動ではやってくれない。

結局、以下のように間にフレームワークプロジェクトを挟む方法が最も簡単だった。

  1. ワークスペースの作成

file > New… > Workspace… で、ワークスペースの作成。

../../../_images/PGWS02.png
  1. アプリケーションプロジェクトの作成

先ほどのワークスペースのWindowの左下の”+”マークから、”New Project…”を選んで、アプリケーションプロジェクトの作成と追加。

この時、プロジェクトの種類はCocoaアプリケーションを選ぶ

../../../_images/PGWS03.png
  1. フレームワークプロジェクトの作成

同じくワークスペースのWindowの左下の”+”マークから、”New Project…”を選んで、フレームワークプロジェクトの作成と追加。

この時、プロジェクトの種類はCocoaフレームワークを選ぶ

../../../_images/PGWS04.png

playgroundでフレームワークをimport出来るように、ここでフレームワークをビルドしておく。

フレームワークの中のソースを変更する毎にビルドしてから、playgroundの実行を行う事。

  1. プレイグラウンドの作成

ワークスペースのWindowの左下の”+”マークから、今度は”New file…”を選んで、Playgroundファイルの作成と追加。

この時、ファイルの種類はPlaygroundを選ぶ。ここで気がついたが、Playgroundはファイルであり、プロジェクトではないために、ファイルの共有が出来ないのかもしれない。

../../../_images/PGWS05.png
  1. playgroundからフレームワークをimportする

フレームワークの名称がPGWS2FMなので、”import PGWS2FM”を追加する。

PlaygroundSupportはplaygroundでNSViewやNSViewControllerを使用するためのユーティリティフレームワーク。

@testableをつけてimportすると、同じモジュールにあるように扱えます。

ここでの目的は、アプリケーションプロジェクトの支援なので、@testableをつけてます。

//: Playground - noun: a place where people can play

import Cocoa
import PlaygroundSupport
@testable import PGWS2FM

var str = "Hello, playground"

そのほかに、playgroundの自動実行の停止や、ショートカットの設定を行うと便利。

使用例1:カスタムViewを作成し、プレイグラウンドで試す

適当なNSViewのサブクラスPGWS2View.swiftをアプリケーションプロジェクトに作る。

import Cocoa

class PGWS2View: NSView
{
    // 背景色
    var backgroundColor: NSColor = NSColor.blue

    override func draw(_ dirtyRect: NSRect)
    {
        super.draw(dirtyRect)

        // Drawing code here.
        backgroundColor.set()
        NSBezierPath.fill(self.bounds)
    }
}

作成後、フレームワークプロジェクトにDrag&Dropして、フレークワークをビルドする。

../../../_images/PGWS06.png

これで、PlaygroundでPGWS2Viewが使えるようになる。以下のソースをPlaygroundに打ち込むとTimeLineに青い四角が現れるはず。

//: Playground - noun: a place where people can play

import Cocoa
import PlaygroundSupport
@testable import PGWS2FM

var str = "Hello, playground"

var theView: PGWS2View
let theRect = NSMakeRect(0,0,100,100)

theView = PGWS2View(frame:theRect)

//theView.backgroundColor = NSColor.black

PlaygroundPage.current.liveView = theView

PlayGroundを実行させると以下のような画面になる。

../../../_images/PGWS07.png

エラーが起きた場合は最初に、以下の3点を確認する事。よく忘れる。

  1. フレームワークのビルドを忘れていないか?
  2. フレームワークにファイルをコピーし忘れていないか?
  3. palygroundをマニュアル起動にしたのに、実行ボタンを押し忘れていないか?

なお、TimeLine表示にするには、Window左上の丸が2つあるマークを押す必要がある。

私は間抜けなのでこれに気がつくのに時間がかかった。

うまく動いたら、コメントアウトされた行を有効にして、黒い四角を表示させてみてください。カスタムViewの作成が捗るような気がしてくるはずです。

使用例2:アプリケーションプロジェクト内のViewControllerをプレイグラウンドで試す

次は、ViewControllerです。storyboadrdから再生したViewControllerを表示させます。

../../../_images/PGWS11.png

ソースコードは、動作確認のための、アクションを2つ。ログを出力後に、ViewControllerを閉じるだけの簡単なコードです。

import Cocoa

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

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

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    @IBAction          func okOperation(_ sender: Any?)
    {
        print("OK_BUTTON")
        self.dismissViewController(self)
    }

    @IBAction override func cancelOperation(_ sender: Any?)
    {
        print("Cancel_BUTTON")
        self.dismissViewController(self)
    }

}

OKボタンとCancelボタンを配置して、actionの設定をします。

../../../_images/PGWS08.png

SotorybordIDを設定します。ここでは、クラス名と同じく、ViewControllerにしてます。

../../../_images/PGWS09.png

最後に、アプリケーションプロジェクトからフレームワークプロジェクトにファイルをDrg&Dropします。ファイルの参照がフレームワークプロジェクトに追加されるようにするためです。

../../../_images/PGWS10.png

ここで、フレームワークのビルドを忘れずに。

これで、PlaygroundでViewControllerが使えるようになる。以下のソースをPlaygroundに打ち込むとTimeLineにボタンが2つ見えるはず

//: Playground - noun: a place where people can play

import Cocoa
import PlaygroundSupport
@testable import PGWS2FM

let theBundle = Bundle(identifier:"com.mindto01s.PGWS2FM")

let theStoryboard = NSStoryboard(name: "Main",
                                     bundle:theBundle)

var vc:ViewController

vc = theStoryboard.instantiateController(withIdentifier: "ViewController") as! ViewController

PlaygroundPage.current.liveView = vc

実行させると、以下のようにボタンが2つ表示される。

../../../_images/PGWS11.png

ここで、OKボタンを押すとログに”OK_BUTTON”と表示され、アクションが実行されていることが確認できます。

ここでのコツは、

  1. Storyboradをフレームワークに登録することを忘れない
  2. フレームワークに入っているリソースはメインバンドル内では無い事を忘れない。

この2点さえ覚えておけば、普通に使えてます。

参考文献とソースコード

プロジェクトファイル