Consider this macOS app code implemented with app delegate lifecycle:
App delegate:
func applicationDidFinishLaunching(_ aNotification: Notification) {
let contentView = ContentView()
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.toolbar = NSToolbar(identifier: "toolbar")
window.title = "hello title"
window.subtitle = "hello subtitle"
window.isReleasedWhenClosed = false
window.center()
window.setFrameAutosaveName("Main Window")
window.contentView = NSHostingView(rootView: contentView)
window.makeKeyAndOrderFront(nil)
}
SwiftUI:
struct ContentView: View {
var body: some View {
NavigationView {
List {
NavigationLink(
destination: ItemView(),
label: {
Label("Something", systemImage: "folder.circle")
})
NavigationLink(
destination: ItemView(),
label: {
Label("Another", systemImage: "pencil.tip.crop.circle")
})
}.listStyle(SidebarListStyle())
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.toolbar {
ToolbarItem {
Button(action: {
print("Button clicked")
}, label: {
Label("Hello", systemImage: "pencil.circle")
})
}
}
}
}
struct ItemView: View {
var body: some View {
Text("Hello, World!")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.toolbar {
ToolbarItem {
Button(action: {
print("Item button")
}, label: {
Label("Itemtool", systemImage: "lock.doc")
})
}
}
}
}
What this does: correctly sets up the window and toolbar look. Toolbar has no buttons though. It looks like this:
What I would like to do: get the toolbar items added from SwiftUI added to the toolbar.
Everything works as expected when I have the window managed by the SwiftUI app lifecycle. However, I need to stick with the app delegate lifecycle for unrelated reasons.
Is this possible? How do I add toolbar buttons from SwiftUI to the toolbar of window that is created by app delegate?
On macOS 11 beta 6 and Xcode 12 beta 6:
ContentView:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
List {
NavigationLink(
destination: ItemView(),
label: {
Label("Something", systemImage: "folder.circle")
})
NavigationLink(
destination: ItemView(),
label: {
Label("Another", systemImage: "pencil.tip.crop.circle")
})
}.listStyle(SidebarListStyle())
.toolbar {
ToolbarItem {
Button(action: {
print("Button clicked")
}, label: {
Label("Hello", systemImage: "pencil.circle")
})
}
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
/* move into the NavigationView
.toolbar {
ToolbarItem {
Button(action: {
print("Button clicked")
}, label: {
Label("Hello", systemImage: "pencil.circle")
})
}
}
*/
}
}
struct ItemView: View {
var body: some View {
Text("Hello, World!")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.navigationTitle("hello title") // add title
.navigationSubtitle("hello subtitle") // add sub title
.toolbar {
ToolbarItem {
Button(action: {
print("Item button")
}, label: {
Label("Itemtool", systemImage: "lock.doc")
})
}
}
}
}
And you need a class for Appdelegate:
class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// do something
}
// others func
}
Last:
@main
struct SomeApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Result:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.