I like to recreate a toolbar similar to Apples Notes App using SwiftUI in a macOS app (I am using Xcode 12.3 and macOS 11.1):
My attempt was to use a Navigation View to get the Master/Detail setup (for now I do not need a third panel like the original Notes App has). I am interested in how to get the appearance right, e.g. background color and behavior of the buttons in the toolbar. I tried out some approaches, the best I came up with for the moment is this for the main file:
import SwiftUI
@main
struct App_Without_Name_in_Window_Top_AreaApp: App {
var body: some Scene {
WindowGroup("") { // <-- The ("") will remove the app name in the toolbar
ContentView()
}
.windowToolbarStyle(UnifiedCompactWindowToolbarStyle())
}
}
And for the content view:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
Text("Master")
.frame(minWidth: 200, maxWidth: 300, minHeight: 300, alignment: .leading)
.padding()
.toolbar {
ToolbarItem(placement: .status) {
Button(action: {
myToggleSidebar()
}) {
Image(systemName: "sidebar.left")
}
}
}
.presentedWindowToolbarStyle(ExpandedWindowToolbarStyle())
Text("Detail")
.frame(minWidth: 200, alignment: .center)
.toolbar {
ToolbarItem(placement: .navigation) {
Button(action: {
print("Button pressed")
}) {
Image(systemName: "bold.italic.underline")
}
}
ToolbarItem(placement: .navigation) {
Button(action: {
print("Button pressed")
}) {
Image(systemName: "lock")
}
}
}
}
.frame(minWidth: 500, minHeight: 300)
}
}
func myToggleSidebar() {
NSApp.keyWindow?.firstResponder?.tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)), with: nil)
}
which yields a result like this:
Now my question is: How can I alter the color of the left and right parts of the toolbar? I also have problems with the behavior of the toolbar. When the master panel's size is increased, the buttons of the right part of the toolbar are disappearing very early although there is a lot of space left:
What do I have to do to prevent it?
Okay, I found a trick that works:
windowStyle
to HiddenTitleBarWindowStyle
, which both hides the title and removes the white background:WindowGroup {
ContentView()
}
.windowToolbarStyle(UnifiedCompactWindowToolbarStyle())
.windowStyle(HiddenTitleBarWindowStyle())
(Note that I don't set the scene name to an empty string, as that's no longer needed and it messed up the window name in the "Window" menu too)
Divider
behind it:Text("Detail")
.frame(minWidth: 200, maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.background(VStack {
Divider()
Spacer()
})
.toolbar { ...
That seems to do it!
What you want is to use
.windowToolbarStyle(UnifiedWindowToolbarStyle(showsTitle: false))
because it preserves the correct behavior when the user tabs the application
Using
.windowToolbarStyle(UnifiedCompactWindowToolbarStyle())
.windowStyle(HiddenTitleBarWindowStyle())
Causes funky behavior when the user opens a new tab due to the coloring of the toolbar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With