LoginSignup
25
20

More than 5 years have passed since last update.

Macでファイルオープン/保存ダイアログを実装する

Posted at

Macでよくみるファイルオープン/保存のダイアログについての用法と実装方法についてです。

Document modalとApp modal

ダイアログにはいくつか種類があり、これらはファイルオープン/保存をするときのシーンによって使い分けるのが良いです。

Document modal (Sheets)

ドキュメント保存時によく出てくるこのダイアログは、特徴としてウィンドウにくっついているので、保存するものとウィンドウの関連が視覚化できます。

sheet_example_2x.png

用いられるシーンとして、

  • ファイル保存, ファイル添付, 印刷などの操作をするとき
  • シングルウィンドウアプリケーションの確認時
  • アプリ終了時確認
  • エラー表示

などがあります。

App modal

ファイルを開くときによく出てくるこのダイアログは他のウィンドウから独立しています。ドキュメントやウィンドウに対して表示するのではなく、アプリケーションに対して表示するイメージです。

nondocument_open_dialog_2x.png

用いられるシーンとして、

  • ファイルオープン
  • アプリ終了時確認
  • エラー表示

などがあります。Document modalと重複するのもがありますが、ポイントはアプリケーションに対して表示する点かと。

実装方法

Document modalを表示する

以下はDocument modalを使って特定の画像ファイル(jpg, png, gif)を保存先パスを表示するサンプルです。

filesave.swift
    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)をローカルから選択してファイル名を取得するためのサンプルです。

fileopen.swift
    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標準のテキストエディットで文書を保存するときに表示されるものです。

スクリーンショット 2016-01-08 12.23.01.png

以下は、ファイル保存を選択するとポップアップメニューで選択した拡張子を表示するサンプルです。

accesory.swift
    // 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")
        }
    })

表示結果

スクリーンショット 2016-01-08 13.57.45.png

参考

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

25
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
20