Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI: how to use NavigationView in macOS?

Tags:

macos

ios

swiftui

I have two separate Xcode projects that I'm using to learn SwiftUI:

  1. A true macOS project (not Catalyst) on Mac.
  2. An iOS project (iPhone).

The following code creates a simple NavigationView with master-detail views:

import SwiftUI

struct ListView : View {
    var body: some View {
        NavigationView {
            List() {
                NavigationButton(destination: Text("detail 1")) {
                    Text("row 1")
                }
                NavigationButton(destination: Text("detail 2")) {
                    Text("row 2")
                }
            }
        }
    }
}

#if DEBUG
struct ListView_Previews : PreviewProvider {
    static var previews: some View {
        ListView()
    }
}
#endif

It works as expected on iOS 👍

But on the macOS project the same code as above doesn't work the same way 🤯

When I launch the app on Mac, I get this window

enter image description here

And when I click on any row, the detail view just collapses/disappears, never showing me detail view.

enter image description here

Any ideas how to fix this? Maybe I'm missing something? Or perhaps this is just a bug?

like image 585
Salavat Khanov Avatar asked Jun 16 '19 08:06

Salavat Khanov


People also ask

What is NavigationView SwiftUI?

NavigationView is one of the most important components of a SwiftUI app, allowing us to push and pop screens with ease, presenting information in a clear, hierarchical way for users.

Does SwiftUI work on Mac?

SwiftUI runs on iOS 13, macOS 10.15, tvOS 13, and watchOS 6, or any future later versions of those platforms.

How do I pop root view in SwiftUI?

One to pop the view from the stack using the SwiftUI presentationMode environment's dismiss() method. A second to pop to the RootView by changing the RootView's id value to a new UUID.

How do I customize my navigation bar in SwiftUI?

To change a navigation bar color in SwiftUI, you apply toolbarBackground modifier to the content view of NavigationStack . NavigationView is deprecated in iOS 16. toolbarBackground accepts two parameters. ShapeStyle : The style to display as the background of the bar.


2 Answers

Here is my code that seems to fix it using Xcode 12.2 beta 3:

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)
                                .listStyle(SidebarListStyle())
            }
            
            .toolbar
            {
                Text("this is not the title")
                Button(action: {})
                {
                    Label("Upload", systemImage: "square.and.arrow.up")
                }
            }
            .navigationTitle("My Title")
            .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)
                    }
                }
            }.frame(width:150)
        }
    }
}

This makes a window like this:

enter image description here

like image 122
iphaaw Avatar answered Oct 14 '22 00:10

iphaaw


I don't have the answer but I'm trying to do the same thing and have a few observations to add, maybe they will help:

Add a destination View:

NavigationButton(destination: DetailView()) {
            Text("Show Detail")
        }

Setting a width on the NavigationView stops the right-hand view from disappearing.

Also, adding

 .onAppear { print("DetailView called") } 

to the detail view shows that, even though it isn't being displayed, the view is in fact called when the button is clicked.

Edit: it's there! The view was hidden by the divider, drag it left to see the detail view.

Edit 2: Xcode beta 2 gives a "'NavigationView' is unavailable in macOS" message.

like image 26
rougement Avatar answered Oct 14 '22 01:10

rougement