'SwiftUI NavigationView on the iPad Pro

I use the Apple SwiftUI tutorial code. Then I set the previewDevice to iPad Pro (12.9-inch). But the preview has something wrong. Does anyone know where the problem is?

SwiftUI preview issue



Solution 1:[1]

You can override the default splitView used on iPad, by having the NavigationView display the same stacked view you see on iPhone, by setting .navigationViewStyle(StackNavigationViewStyle())

Quite helpful during development and debugging, and when you have not developed the detailedView() yet.

Solution 2:[2]

In my case what make the difference was using StackNavigationViewStyle and no padding were needed.

NavigationView {
  ...
}
.navigationViewStyle(StackNavigationViewStyle())

Solution 3:[3]

Slide the drawer from the left side of the screen.

If you would to remove the drawer and have it constant, you can do the following (note the padding is what makes the drawer constant):

.navigationViewStyle(DefaultNavigationViewStyle())
        .padding(0)

or

.navigationViewStyle(DoubleColumnNavigationViewStyle())
        .padding(0)

Note: This does not currently work perfectly with all iPad views. For example on the iPad 9.7in, the above padding(0) would make the portrait view have the list, but the landscape view have the slideout. This would also not work correctly on the iPad 12.9in. If you don't have the padding included, it works in landscape on the 9.7in, but not in portrait.

Solution 4:[4]

It looks like the master view (the one on the left) is hidden on iPads running iOS 13 by design. The master view is there, you can pull it out from the left edge of the screen.

Unfortunately, there is currently no API to opt-out of this behavior other than applying a non-zero padding for the leading edge:

var body: some View {
    GeometryReader { geometry in
        NavigationView {
            self.content
        }.padding(.leading, self.leadingPadding(geometry))
    }
}

private func leadingPadding(_ geometry: GeometryProxy) -> CGFloat {
    if UIDevice.current.userInterfaceIdiom == .pad {
        // A hack for correct display of the SplitView in SwiftUI on iPad
        return geometry.size.width < geometry.size.height ? 0.5 : -0.5
    }
    return 0
}

Solution 5:[5]

You have embedded your body in NavigationView.In iPad,you have to slide the drawer from left side to view your content view.

Remove NavigationView and observe the behaviour

To override default behaviour, use below code

NavigationView { ... } .navigationViewStyle(DoubleColumnNavigationViewStyle()) .padding()

Solution 6:[6]

Using the code provided by nalexn I came up with this as the solution.

As commented by matthew in the same post iPhones in landscape mode will still cause the drawer to be hidden thus, using StackNavigationViewStyle() is more suitable for iPhone whilst for iPad it will use the DoubleColumnNavigationViewStyle()

    var body: some View {
    GeometryReader{ geo in
      if (UIDevice.current.userInterfaceIdiom == .pad){
        NavigationView{
          self.makeContents()
        }.navigationViewStyle(DoubleColumnNavigationViewStyle())
          .padding(.leading, geo.size.width < geo.size.height ? 0.25 : 0)
      }else{
        NavigationView{
          self.makeContents()
        }.navigationViewStyle(StackNavigationViewStyle())
      }
    }
  }

Hope this helps anyone that comes to this post after me :D

Solution 7:[7]

Correct Solution!

All the answers here were unhelpful as they were missing a vital view to be shown before a selection has been made in the NavigationView. This is necessary on iPad if both views are to be visible at the start!

To use .columns in NavigationView, we should provide a default Detail view that is to be shown, when nothing has been selected, i.e. WordView("").

struct ContentView: View {
    @State private var words: [String] = []
    @State private var selected: String?
    @FocusState private var isFocused: Bool
    
    var body: some View {
        NavigationView {
            List(selection: $selected) {
                ForEach(words) { word in
                    NavigationLink(tag: word, selection: $selected) {
                        WordView(word)
                    } label: {
                        Text(word)
                    }
                }
                .task {
                    isFocused = true
                }
            }
            .navigationTitle("Words")
            .navigationViewStyle(.columns)

            // Detail view shown when not is selected
            WordView("")
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sondergaard
Solution 2 ideastouch
Solution 3
Solution 4 nalexn
Solution 5
Solution 6 Malcolm
Solution 7