Search code examples
swiftuitoolbarmacos-big-sur

SwiftUI: How to set the title for the toolbar on macOS 11?


I have a SwiftUI app that has two columns and a toolbar. I'm trying to emulate the latest macOS applications and use the toolbar in the same way that Mail does, i.e. select a sidebar item and show that as the title of the window.

Here is my code:

import SwiftUI

var listItems = ["Item 1", "Item 2", "Item 3", "Item 4"]
var secondItems = ["Second 1", "Second 2", "Second 3", "Second 4"]

struct ContentView: View
{
    
    @State var select: String? = "Item 1"
    var body: some View
    {
        VStack
        {
            NavigationView
            {
                List
                {
                    ForEach((0..<listItems.count), id: \.self)
                    {index in
                        NavigationLink(destination: SecondView(), tag: listItems[index], selection: $select)
                        {
                            Text(listItems[index])
                                .padding(.vertical, 2.0)
                        }
                    }
                    Spacer()
                }.frame(width:160)
            }
            
            .toolbar
            {
                Text("this is not the title")
                Button(action: {})
                {
                    Label("Upload", systemImage: "square.and.arrow.up")
                }
            }
        }
    }
}

struct SecondView: View 
{
    var body: some View 
    {
        NavigationView 
        {
            List
            {
                ForEach((0..<secondItems.count), id: \.self)
                {index in
                    NavigationLink(destination: Text(secondItems[index]))
                    {
                        Text(secondItems[index])
                            .frame(height: 20)
                    }
                }
            }.frame(width:150)
        }
        
    }
}

So I get a toolbar like this:

enter image description here

but how do I set the title of the window in the toolbar when I select an item in the first list?


Solution

  • Here is how I solved it:

    import SwiftUI
    
    var listItems = ["Item 1", "Item 2", "Item 3", "Item 4"]
    var secondItems = ["Second 1", "Second 2", "Second 3", "Second 4"]
    struct ContentView: View
    {
        
        @State var select: String? = "Item 1"
        var body: some View
        {
            VStack
            {
                NavigationView
                {
                    List
                    {
                        ForEach((0..<listItems.count), id: \.self)
                        {index in
                            NavigationLink(destination: SecondView(), tag: listItems[index], selection: $select)
                            {
                                Text(listItems[index])
                                    .frame(height: 20)
                            }
                        }
                        Spacer()
                        
                    }
                                    .listStyle(SidebarListStyle())
                }
                
                .toolbar
                {
                    Text("this is not the title")
                    Button(action: {})
                    {
                        Label("Upload", systemImage: "square.and.arrow.up")
                    }
                }
                .navigationTitle(select!)
                .navigationSubtitle("\(listItems.count) records")
                .navigationViewStyle(DoubleColumnNavigationViewStyle())
            }
        }
    }
    
    struct SecondView: View {
    
        var body: some View {
            NavigationView {
                List
                {
                    ForEach((0..<secondItems.count), id: \.self)
                    {index in
                        NavigationLink(destination: Text(secondItems[index]))
                        {
                            Text(secondItems[index])
                                .frame(height: 20)
                        }
                    }
                }
            }
        }
    }