LoginSignup
1
1

More than 1 year has passed since last update.

【SwiftUI】macでフローティングウィンドウを表示する方法

Last updated at Posted at 2023-03-24

はじめに

macアプリでは、クイックメモやカラーピッカーなどでフローティングウィンドウが使われます。私が以前リリースした、プレゼンター向けmac用タイマーアプリ「FloatingTimer」でもフローティングウィンドウを使用しました。
今回は、その時に使用したウィンドウを常に最前面に表示する技術を紹介します。

NSPanel

macアプリでモーダルウィンドウを表示するには、NSPanelを使用します。
NSPanelを使って、フローティングウィンドウを実現できます。

NSHostingController

NSPanelはAppKitのクラスであるため、SwiftUIのViewを表示するには一度NSViewControllerに変換する必要があります。

その際に利用するのが、NSHostingControllerです。NSHostingControllerを使うとSwiftUIのViewをNSViewControllerに変換することができます。NSHostingControllerを利用することで、SwiftUIとAppKitを組み合わせたアプリケーションを開発することができます。

コード解説

以下のコードを使って、簡単なフローティングウィンドウを作成することができます。

import SwiftUI

struct ContentView: View {
     var body: some View {
         VStack {
             Button("button") {
                 let view = Text("hello")
                     .frame(minWidth: 200, minHeight: 200)
                     .frame(maxWidth: .infinity, maxHeight: .infinity)
                 let controller = NSHostingController(rootView: view)
                 
                 let panel = NSPanel(
                     contentRect: .zero,
                     styleMask: [
                         .closable,
                         .miniaturizable,
                         .nonactivatingPanel,
                         .titled,
                         .resizable
                     ],
                     backing: .buffered,
                     defer: false)
                 panel.contentViewController = controller
                 panel.level = .floating
                 panel.collectionBehavior = [
                     .canJoinAllSpaces,
                     .fullScreenAuxiliary
                 ]
                 panel.isMovableByWindowBackground = true
                 panel.center()
                 panel.makeKeyAndOrderFront(nil)
             }
         }
         .padding()
     }
}

このコードでは、Buttonをタップすると、フローティングウィンドウが表示されます。

ポイントは以下の7点です。

  • styleMask(後述)
  • contentViewControllerにNSHostingControllerをセット
  • levelプロパティ:ウィンドウの表示レベルを設定するためのプロパティ。floatingにすることで最前面に表示できる。
  • collectionBehaviorプロパティ(後述)
  • isMovableByWindowBackgroundプロパティ:trueにするとウィンドウの背景部分をドラッグしてウィンドウを移動できる。
  • centerメソッド:ウィンドウを中心に配置できる。
  • makeKeyAndOrderFrontメソッド:ウィンドウをアクティブにして、画面上に最前面に表示する

styleMask

NSPanelのstyleMaskは、ウィンドウのスタイルを設定するためのオプションです。
ここでは、styleMaskのパラメータとして以下のオプションを使用しています。

  • closable: ウィンドウを閉じるボタンを含める。
  • miniaturizable: ウィンドウを最小化するボタンを含める。
  • nonactivatingPanel: ウィンドウをアクティブ化させない。
  • titled: タイトルバーを表示する。
  • resizable: ウィンドウのサイズを変更できるようにする。

collectionBehavior

NSPanelのcollectionBehaviorプロパティは、ウィンドウが複数スペースにまたがるときの動作を設定するためのオプションです。上記の例では、.canJoinAllSpacesと.fullScreenAuxiliaryを設定しています。

  • .canJoinAllSpaces: ウィンドウを複数スペースで共有することができる。
  • .fullScreenAuxiliary: フルスクリーンアプリケーションの画面の上にウィンドウが表示されるようになる

まとめ

SwiftUI製macアプリでフローティングウィンドウを表示する方法を解説しました。これを参考にして、macアプリで様々なフローティングウィンドウを実現してみてください。


ご覧いただきありがとうございました。

🐦 Twitter: @shota_appdev

📱 個人アプリ: Symbols Explorer

1
1
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
1
1