Macでよくみるファイルオープン/保存のダイアログについての用法と実装方法についてです。
Document modalとApp modal
ダイアログにはいくつか種類があり、これらはファイルオープン/保存をするときのシーンによって使い分けるのが良いです。
Document modal (Sheets)
ドキュメント保存時によく出てくるこのダイアログは、特徴としてウィンドウにくっついているので、保存するものとウィンドウの関連が視覚化できます。
用いられるシーンとして、
- ファイル保存, ファイル添付, 印刷などの操作をするとき
- シングルウィンドウアプリケーションの確認時
- アプリ終了時確認
- エラー表示
などがあります。
App modal
ファイルを開くときによく出てくるこのダイアログは他のウィンドウから独立しています。ドキュメントやウィンドウに対して表示するのではなく、アプリケーションに対して表示するイメージです。
用いられるシーンとして、
- ファイルオープン
- アプリ終了時確認
- エラー表示
などがあります。Document modalと重複するのもがありますが、ポイントはアプリケーションに対して表示する点かと。
実装方法
Document modalを表示する
以下はDocument modalを使って特定の画像ファイル(jpg, png, gif)を保存先パスを表示するサンプルです。
let savePanel = NSSavePanel()
savePanel.message = "保存するで" // ダイアログに表記される説明
savePanel.directoryURL = NSURL(fileURLWithPath: "\(NSHomeDirectory())/Desktop)") // デフォルトで表示されるフォルダ
savePanel.allowedFileTypes = ["gif","jpg","png"]
// jpg,png,gifのみ保存可能にする(イレギュラーな拡張子の場合はgifになる)
savePanel.beginSheetModalForWindow(self.window!, completionHandler: { (num: Int) -> Void in
if num == NSModalResponseOK {
let filePath = savePanel.URL!.absoluteString
let decoadPath :String! = filePath.stringByRemovingPercentEncoding // 日本語ファイル対応
NSLog("\(decoadPath)")
} else {
NSLog("Canceled")
}
})
App modalを表示する
以下はApp modalを使って特定の画像ファイル(jpg, png, gif)をローカルから選択してファイル名を取得するためのサンプルです。
let openPanel :NSOpenPanel = NSOpenPanel()
openPanel.canChooseFiles = true // ファイル選択を許可する
openPanel.canChooseDirectories = false // フォルダ選択は禁止する
openPanel.allowsMultipleSelection = true // 複数選択を許可する
openPanel.message = "開くで" // ダイアログに表記される説明
// jpg,png,gifのみ選択可能にする
openPanel.allowedFileTypes = ["gif","jpg","png"]
openPanel.beginWithCompletionHandler({ (num) -> Void in
if num == NSModalResponseOK {
for fileURL in openPanel.URLs {
let filePath :String! = fileURL.resourceSpecifier
let decoadPath :String! = filePath.stringByRemovingPercentEncoding // 日本語ファイルの場合
NSLog("\(decoadPath)")
}
} else if num == NSModalResponseCancel {
NSLog("Canceled")
}
})
Accessory Viewを表示する
Panel上で何かユーザーに操作させたい場合、AccessoryViewを使ってダイアログを拡張します。
以下の例はMac標準のテキストエディットで文書を保存するときに表示されるものです。

以下は、ファイル保存を選択するとポップアップメニューで選択した拡張子を表示するサンプルです。
// Viewの設定
let accessoryView = NSView(frame: CGRectMake(0, 0, 270, 50))
let popup = NSPopUpButton(frame: CGRectMake(130, 10, 120, 25))
let label = NSTextField(frame: CGRectMake(20, 15, 100, 18))
popup.addItemsWithTitles(["JPEG", "PNG", "GIF"])
label.stringValue = "拡張子 : "
label.alignment = NSTextAlignment.Right
label.bordered = false
label.selectable = false
label.editable = false
label.backgroundColor = NSColor.clearColor()
accessoryView.addSubview(popup)
accessoryView.addSubview(label)
let savePanel = NSSavePanel()
savePanel.message = "保存するで" // ダイアログに表記される説明
savePanel.directoryURL = NSURL(fileURLWithPath: "\(NSHomeDirectory())/Desktop)") // デフォルトで表示されるフォルダ
savePanel.allowedFileTypes = ["gif","jpg","png"]
savePanel.accessoryView = accessoryView
savePanel.beginSheetModalForWindow(self.window!, completionHandler: { (num: Int) -> Void in
if num == NSModalResponseOK {
NSLog("\(popup.selectedItem?.title)")
} else {
NSLog("Canceled")
}
})
表示結果

参考
Dialogs - OS X Human Interface Guidelines
セーブパネルの使い方とシートダイアログの呼び出し方 - Repeating Motif Wonderland