Any experience with SwifUI NavigationView in landscape on iPhone XR simulator?
Asked Answered
R

4

7

I tried running my app in landscape on an iPhone XR simulator and got a blank screen.

The code below is my test. It works correctly on an iPhone 8 simulator and also not the iPhone XR simulator if I remove the NavigationView.

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            GeometryReader { gp in
                VStack(alignment: HorizontalAlignment.center) {
                    Text("Width: \(gp.size.width)")
                    Text("Height: \(gp.size.height)")
                }
            }
        }
    }
}

I expect that I will see the size of the screen in both landscape and portrait.

Does anyone have any experience with this combination?

Ruse answered 4/8, 2019 at 6:49 Comment(0)
H
17

There is nothing wrong. It is just that when a big iPhone is in landscape, its horizontal size class is set to .regular, instead of .compact. Think of it, as if it were an iPad.

You can verify it, by sliding from the left size of your screen:

enter image description here

If you change your code to add a default view when nothing is selected, you get this other look:

enter image description here

struct ContentView: View {
    var body: some View {
        NavigationView {
            GeometryReader { gp in
                VStack(alignment: HorizontalAlignment.center) {
                    Text("Width: \(gp.size.width)")
                    Text("Height: \(gp.size.height)")
                    NavigationLink(destination: Text("Something got selected")) { Text("Select something") }
                }

            }

            Text("No Selection")
        }
    }
}

And if you want to force it to .compact, you do the following:

enter image description here

struct ContentView: View {
    var body: some View {
        NavigationView {
            GeometryReader { gp in
                VStack(alignment: HorizontalAlignment.center) {
                    Text("Width: \(gp.size.width)")
                    Text("Height: \(gp.size.height)")
                    NavigationLink(destination: Text("Something got selected")) { Text("Select something") }
                }

            }

            Text("No Selection")
        }.environment(\.horizontalSizeClass, .compact)
    }
}
Hankow answered 4/8, 2019 at 9:49 Comment(2)
OK, I accept that that is what is happening but why only in a NavigationView?Ruse
That is just how they work. The same thing happens with UINavigationController.Hankow
W
1

Adding this modifier to the NavigationView works disabling master - detail views.

NavigationView {
  // Code
}
.environment(\.horizontalSizeClass, .compact) 
Whipping answered 12/11, 2019 at 7:29 Comment(2)
Thanks but that was exactly what @Hankow wrote.Ruse
Yes, I just wanted to put a quick answer. I just started with stack overflow, sorry for the redundancy.Whipping
F
1

Another way to solve this is to force the NavigationView to stack style.

NavigationView {
    Text("Hello World")
    }.navigationViewStyle(StackNavigationViewStyle())

Or the newer:

NavigationView {
    Text("Hello World")
    }.navigationViewStyle(.stack)
Fusionism answered 11/11, 2021 at 18:40 Comment(0)
A
0

This happened to me on the iPhone 11, when I turned it to landscape mode it replaced the NavigationView with a NavigationSplitView at #preview, emulator and iPhone. It's funny because this doesn't happen to me on an iPhone Xs or an iPhone 12 in landscape mode.

On iOS, especially on larger models or screens with more available real estate like the iPhone 11 in landscape mode, SwiftUI may switch to a NavigationSplitView layout to make better use of space.

My first solution to the problem was to use:

NavigationView {
    AnyView()
}.navigationViewStyle(.stack)

After that reading more about the problem i read this at Apple documentation https://developer.apple.com/documentation/swiftui/navigationviewstyle:

protocol NavigationViewStyle Deprecated

Replace a styled NavigationView with a NavigationStack or NavigationSplitView. For more information, see Migrating to new navigation types.

So I decided to change the NavigationView for a NavigationStack as stated at documentation:

NavigationStack {
    AnyView()
}
Amhara answered 4/10 at 8:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.