Present MenuBarExtra window on app launch? #5
-
I'm trying to automatically present the MenuBarExtra window on first app launch, so far this approach doesn't appear to work. Am I missing something obvious? @main
struct MyApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@ObservedObject var appState = AppState.shared
var body: some Scene {
MenuBarExtra("MyApp", systemImage: "music.note.tv") {
MenuBarExtraView()
.frame(minWidth: 800)
}
.menuBarExtraStyle(.window)
.menuBarExtraAccess(isPresented: $appState.menuBarViewIsPresented)
}
}
class AppState: ObservableObject {
static let shared = AppState()
@Published var menuBarViewIsPresented: Bool = false
}
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
AppState.shared.menuBarViewIsPresented = true
}
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Doing things on app launch with SwiftUI is tricky. One issue may be that AppState is a global singleton when it should probably only be instanced in MyApp and passed by environment to child views. It’s better if you are able to mutate SwiftUI state from within a SwiftUI context. There is a slightly clunky way but it works: @main struct MyApp: App {
@Environment(\.scenePhase) private var scenePhase
@State private var isLaunched: Bool = false
@ObservedObject var appState = AppState()
var body: some Scene {
MenuBarExtra("MyApp", systemImage: "music.note.tv") {
MenuBarExtraView()
.frame(minWidth: 800)
}
.menuBarExtraStyle(.window)
.menuBarExtraAccess(isPresented: $appState.menuBarViewIsPresented)
.onChange(of: scenePhase) { newValue in
switch newValue {
case .active:
if !isLaunched {
isLaunched = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
appState.menuBarViewIsPresented = true
}
}
default: break
}
}
}
} |
Beta Was this translation helpful? Give feedback.
-
BTW, we can also use |
Beta Was this translation helpful? Give feedback.
Doing things on app launch with SwiftUI is tricky.
One issue may be that AppState is a global singleton when it should probably only be instanced in MyApp and passed by environment to child views.
It’s better if you are able to mutate SwiftUI state from within a SwiftUI context.
There is a slightly clunky way but it works: