[SwiftUI][macOS編] NSOpenPanel の使用方法

SwiftUI macOS

NSOpenPanel を使用すると、ファイルやディレクトリを選択するためのパネルを表示して、ユーザーに選択させることができます。
本記事では NSOpenPanel の使用方法について説明します。

スポンサーリンク

環境

OS: macOS Big Sur 11.6
Xcode: 13
Swift: 5.2.4

スポンサーリンク

NSOpenFile の基本使用方法

NSOpenPanel の基本使用例を以下に示します。
はじめに ① NSOpenPanel のインスタンスを作成し、② NSOpenPanel の表示をします。NSPanelを表示する際は、インスタンスの runModal メソッドを使用します。
選択されたファイル名は url プロパティに格納されています。lastPathComponent を使用すると選択されたファイル名のみを取得することができます。

struct ContentView: View {
  @State var filename = "Filename"
  @State var showFileChooser = false

  var body: some View {
    HStack {
      Text(filename)
      Button("select File")
      {
        // ①インスタンス生成
        let panel = NSOpenPanel()
        // ② NSOpenPanel の表示
        if panel.runModal() == .OK {
            // ③選択されたファイル名の表示
            self.filename = panel.url?.lastPathComponent ?? ""
        }
      }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}

Button クリックで NSOpenPanel を表示

Button クリックで NSOpenPanel を表示

NSOpenPanel の表示

NSOpenPanel の表示

スポンサーリンク

パネルのタイトルを設定する

message プロパティを使用するとパネルのタイトルを設定することができます。以下の②の部分です。この例ではパネルのタイトルを「画像ファイルを開く」に設定しています。

struct ContentView: View {
  @State var filename = "Filename"
  @State var showFileChooser = false

  var body: some View {
    HStack {
      Text(filename)
      Button("select File")
      {
        // ① インスタンス生成
        let panel = NSOpenPanel()
        // ② パネルのタイトルを設定する
        panel.message = "画像ファイルを開く"
        // ③ NSOpenPanel の表示
        if panel.runModal() == .OK {
            // ④選択されたファイル名の表示
            self.filename = panel.url?.lastPathComponent ?? ""
        }
      }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}
パネルタイトルの設定例

パネルタイトルの設定例

スポンサーリンク

選択可能なファイルの拡張子を指定する

NSOpenPanel は allowedFileTypes プロパティを使用して選択可能なファイルの拡張子を指定することができます。
以下に例を示します。②の部分でファイルの種類を指定しています。 allowedFileTypes プロパティは文字配列ですので、複数の拡張子を指定することができます。

struct ContentView: View {
  @State var filename = "Filename"
  @State var showFileChooser = false

  var body: some View {
    HStack {
      Text(filename)
      Button("select File")
      {
        // ①インスタンス生成
        let panel = NSOpenPanel()
        // ② 選択可能なファイルの拡張子を指定
        panel.allowedFileTypes = ["jpg","jpeg"]
        // ③ NSOpenPanel の表示
        if panel.runModal() == .OK {
            // ④選択されたファイル名の表示
            self.filename = panel.url?.lastPathComponent ?? ""
        }
      }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}
選択可能な拡張子の指定例

選択可能な拡張子の指定例

スポンサーリンク

ディレクトリを選択可能にする

NSOpenPanel ではディレクトリを選択することもできます。ディレクトリを選択可能にする場合は canChooseDirectories プロパティに true を指定します。
以下に例を示します。この例では②の部分でディイレクトリの選択を可能にしています。

struct ContentView: View {
  @State var dirname = "Directory name"
  @State var showFileChooser = false

  var body: some View {
    HStack {
      Text(dirname)
      Button("select Directory")
      {
        // ①インスタンス生成
        let panel = NSOpenPanel()
        // ② ディレクトリの選択を許可する
        panel.canChooseDirectories = true
        // ③ ファイルの選択を不可にする
        panel.canChooseFiles = false
        // ④ NSOpenPanel の表示
        if panel.runModal() == .OK {
            // ⑤ 選択されたファイル名の表示
            self.dirname = panel.url?.lastPathComponent ?? ""
        }
      }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}

ディレクトリを選択可能にする例

ディレクトリを選択可能にする例

スポンサーリンク

複数のファイルやディレクトリを選択できるようにする

NSOpenPanel は allowsMultipleSelection プロパティに true を指定することで、複数のファイルやディレクトリを選択できます。
以下に例を示します。この例では②で複数ファイルや複数ディレクトリの選択を許可しています。また、選択された複数のファイルやディレクトリの絶対パスの取り出しは⑥の部分で行っています。

struct ContentView: View {
  @State var dirname = "Directory name"
  @State var showFileChooser = false

  var body: some View {
    HStack {
      Text(dirname)
      Button("select Directory")
      {
        // ①インスタンス生成
        let panel = NSOpenPanel()
        // ② 複数ファイル/ディレクトリの選択を許可する
        panel.allowsMultipleSelection = true
        // ③ ディレクトリの選択を許可する
        panel.canChooseDirectories = true
        // ④ ファイルの選択を不可にする
        panel.canChooseFiles = true
        // ⑤ NSOpenPanel の表示
        if panel.runModal() == .OK {
            // ⑥ 選択されたファイル名の表示
            for url in panel.urls {
                print(url.absoluteString)
            }
        }
      }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}
複数のファイルやディレクトリを選択可能にする例

複数のファイルやディレクトリを選択可能にする例

コメント

タイトルとURLをコピーしました