1
3

【SwiftUI】Macアプリの設定ウインドウを作成する

Last updated at Posted at 2023-01-11

はじめに

MenuBarExtraでメニューバーアプリを開発していて環境設定を作成しようと思ったところで詰まったので記事にしておきます。
全てはKyomeさんのおかげです。

こんな感じでみんな困ってるっぽいです。

サンプルアプリ

画面収録_2023-01-11_21_23_20_AdobeExpress.gif

実装

AppDelegate
import AppKit

class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
    private var settingsWindow: NSWindow? {
        return NSApp.windows.first(where: { window in
            window.frameAutosaveName == "com_apple_SwiftUI_Settings_window"
        })
    }

    func applicationDidFinishLaunching(_: Notification) {}

    func openPreferences() {
        if #available(macOS 13, *) {
            NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
        } else {
            NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil)
        }
        guard let window = settingsWindow else { return }
        if window.canBecomeMain {
            window.orderFrontRegardless()
            window.center()
            NSApp.activate(ignoringOtherApps: true)
        }
    }
}
〇〇App
import SwiftUI

@main
struct swiftui_macos_sampleApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var delegate
    var body: some Scene {
        MenuBarExtra {
            ContentView(delegate: delegate)
        } label: {
            Image(systemName: "paperplane.fill")
        }
        .menuBarExtraStyle(.window)

        Settings {
            SettingView()
        }
    }
}
ContentView
import SwiftUI

struct ContentView: View {
    @ObservedObject var delegate: AppDelegate
    var body: some View {
        VStack {
            Label("環境設定", systemImage: "slider.horizontal.3")
                .onTapGesture {
                    delegate.openPreferences()
                }
        }
        .frame(width: 200, height: 100)
    }
}
SettingView
import SwiftUI

struct SettingView: View {
    var body: some View {
        TabView {
            Text("General")
                .tabItem {
                    Label("General", systemImage: "gear")
                }
            Text("License")
                .tabItem {
                    Label("License", systemImage: "book")
                }
        }
        .frame(width: 300, height: 300)
    }
}

おわり

まじで困ってたので助かりました

参考記事

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