SwiftUI NavigationSplitView column visibility on iPhone?

339 Views Asked by At

I'm trying to create a 3-column layout in SwiftUI.

The first column is a LazyVGrid of selectable items. The selection then impacts a list of items in a content view (second column) which also isn't a SwiftUI list but a VStack + other views in a scrollview. Selecting items on that column impacts the detail view.

I got it all to work on the iPad, but this is because the iPad displays multiple columns at a time and NavigationSplitView supports gestures on the iPad as well as column visibility settings in code.

The problem is that I can't find a way to programmatically navigate from one column to another on the iPhone as it doesn't seem to respond to column visibility bindings.

I initially had it working with navigation links for each item on my grid where the destination was set to a view, but the code smelled pretty bad.

Eventually, I came up with the code below. In the first column I have my grid view which has a custom onSelect modifier that I trigger whenever an item is selected. That's where I'm trying to change column visibility. I tried setting vm.navigationColumnVisibility = .detailOnly, but the iPhone seems to ignore it.

I was able to get it to work exactly as expected by changing the grid to a List. The selection property/Binding in the List view seemed to trigger navigation on the iPhone. However, that's not the desired UI/UX.

Any advice on how to trigger navigation between columns programatically on the iPhone or a better way to adapt this code to achieve the described UI/UX?

struct JNavSplitView: View {
    @EnvironmentObject var vm: JNavSplitViewModel
    @State private var book: Book? = nil
    @State private var entry: Entry? = nil
        
    var sheet: some View {
        #if os(macOS)
        JEntryCreateFormMacOS(book: book)
        #else
        JEntryCreateForm(book: book)
            .onCreate { entry in
                self.entry = entry
            }
        #endif
    }
    
    var body: some View {
        NavigationSplitView(columnVisibility: $vm.navigationColumnVisibility) {
            BooksGridView(selected: $book)
                .onSelect { book in
                    self.entry = book.getEntries(forDate: Date()).first
                }
        } content: {
            BookEntriesView(book: book, selected: $entry)
        } detail: {
            PageCollectionView(entry: $entry)
        }
        .navigationViewStyle(DoubleColumnNavigationViewStyle())
        #if os(macOS)
        .toolbarBackground(Color("Purple 1000"), for: .windowToolbar)
        #endif
        .environmentObject(vm)
        .sheet(isPresented: $vm.presentNewEntryForm, content: {
            sheet
        })
    }
    
}
0

There are 0 best solutions below