简体   繁体   中英

Docked Sidebar on iPad in portrait orientation with SwiftUI

SwiftUI helpfully gives you NavigationView which easily lets you define a sidebar and main content for iPad apps that automatically collapse for iPhones.

I have an app and everything works as expected except on iPad, in portrait mode, the sidebar is hidden by default and you are forced click a button to show it.

All I want is to force the sidebar to always be visible, even in portrait mode. And make it work the same way as the settings app.

I'm even willing to use a UIKit view wrapped for SwiftUI, but wrapping NavigationController seems very very challenging.

Is there a better way?

Without your specific code I can't be sure but I think you are describing the initial screen that shows on iPad. That is actually a "ThirdView". You can see it with the code below.

And I am answering the "better way" portion of your question. Which for me is a way of just "graciously" dealing with it.

struct VisibleSideBar2: View {
    var body: some View {
        NavigationView{
            List(0..<10){ idx in
                NavigationLink("SideBar \(idx)", destination: Text("Secondary \(idx)"))
            }
            Text("Welcome Screen")
        }
    }
}

It is even more apparent if you have a default selection in your "Secondary View" because now you have to click "Back" twice to get to the SideBar

struct VisibleSideBar1: View {
    @State var selection: Int? = 1
    var body: some View {
        NavigationView{
        List(0..<10){ idx in
            NavigationLink(
                destination: Text("Secondary \(idx)"),
                tag: idx,
                selection: $selection,
                label: {Text("SideBar \(idx)")})
        }
            Text("Third View")
        }
    }
}

A lot of the "solutions" out there for this just turn the NavigationView into a Stack but then you can't get the double column.

One way of dealing with it is the what is depicted in VisibleSideBar2 . You can make/embrace a nice "Welcome Screen" so the user isn't greeted with a blank screen and then the natural navigation instincts kick in. You only see the "Welcome Screen" on iPad Portrait and on Catalyst/MacOS where Stack is unavailable.

Or you can bypass the third screen by using isActive in a NavigationLink and using the Sidebar as a menu like View

struct VisibleSidebar3: View{
    @State var mainIsPresented = true
    var body: some View {
        NavigationView {
            ScrollView{
                NavigationLink(
                    destination: Text("Main View").navigationTitle("Main"),
                    isActive: $mainIsPresented,
                    label: {
                        Text("Main View")
                    })
                NavigationLink("List View", destination: ListView())
                
            }.navigationTitle("Sidebar")
            //Not visible anymore
            Text("Welcome Screen")
        }
    }
}
struct ListView: View{
    var body: some View {
        List(0..<10){ idx in
            NavigationLink("SideBar \(idx)", destination: Text("Secondary \(idx)"))
        }.navigationTitle("List")
        
    }
}

Like I said my answer isn't really a way of "fixing" the issue. Just dealing with it. To fix it we would have to somehow dismiss the "Third Screen/Welcome Screen". Then manipulate the remaining UISplitViewController (Several SO questions on this) to show both the SideBar/Master and the Detail View.

In UIKit it seems to have been done a lot, if you search SO, you will find a way to create a UISplitViewController that behaves like Settings .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM