Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI macOS Xcode Style Toolbar

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): enter image description here

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: enter image description here

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: enter image description here

What do I have to do to prevent it?

like image 572
DaPhil Avatar asked Dec 26 '20 09:12

DaPhil


2 Answers

Okay, I found a trick that works:

  1. Set the scene's 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)

  1. To force a divider between the toolbar and the detail view content, stretch the detail content to fill the whole space and put a Divider behind it:
Text("Detail")
    .frame(minWidth: 200, maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
    .background(VStack {
        Divider()
        Spacer()
    })
    .toolbar { ...

That seems to do it!

enter image description here

like image 163
Adam Avatar answered Oct 22 '22 05:10

Adam


What you want is to use

.windowToolbarStyle(UnifiedWindowToolbarStyle(showsTitle: false))

because it preserves the correct behavior when the user tabs the application

Good

Using

.windowToolbarStyle(UnifiedCompactWindowToolbarStyle())
.windowStyle(HiddenTitleBarWindowStyle())

Causes funky behavior when the user opens a new tab due to the coloring of the toolbar.

funky

like image 6
JuJoDi Avatar answered Oct 22 '22 06:10

JuJoDi