SwiftUI NavigationView vs NavigationStack for iOS 15/16
Asked Answered
P

2

8

I'm trying to make my iPhone apps (targeting iOS 15 and above) fully compatible with iOS 16 without success!

I don't know how to have NavigationView for iOS 15 and NavigationStack for iOS 16 in the same piece of code.

The code above isn't accepted by Xcode:

if #available(iOS 16, *) {
   NavigationStack {
} else {
   NavigationView {
}

From: SwiftUI NavigationView/Stack if available iOS 15/16

I guess that creating a custom container, as suggested by @timmy, will be the only solution. But I don't know how to proceed.

What's the solution then?

Presswork answered 13/9, 2022 at 9:47 Comment(0)
G
17

Personally I wouldn't use NavigationStack unless I would target iOS 16+ but if you want to do that you could make your own Navigation Wrapper

struct MyNavigation<Content>: View where Content: View {
    @ViewBuilder var content: () -> Content
    
    var body: some View {
        if #available(iOS 16, *) {
            NavigationStack(root: content)
        } else {
            NavigationView(content: content)
        }
    }
}

and then just use it, like you would NavigationStack or NavigationView and on iOS 15 or older it would use NavigationView and on iOS 16 or newer it would use NavigationStack

Your code isn't accepted by Xcode because it isn't valid. You cannot have a { without a } in the same block.

Galliot answered 13/9, 2022 at 10:9 Comment(4)
Thanks a lot @hallo. Actually, NavigationView seems to work fine on iOS 16 but I guess it will be, soon or later, obsoleted so I would prefer to be ready. I'm just wondering something: where should I place this piece of code? On one View.swift file and use it everywhere OR on every View.swift files before the main struct? Thanks again!Presswork
Alright, I finally used your piece of code into a single View.swift file and refer to it (the struct name) on every other files. It works like a charm! Also, this is the first time I'm using a custom view on my apps, I'm so happy. Thank you so much @hallo.Presswork
@Galliot How to pop to a specific view? Is there any sample code?Jard
Does Content have to be a func "...var content: () -> Content", or can it be just a var: "...var content: Content"? tyBogor
A
2

I have found that using NavigationView can present problems on both iPhone and iPad apps running under iOS 16, even though NavigationView is only deprecated for now. On an iPhone, views reached from a NavigationLink often close themselves as soon as they are opened. On an iPad, the same problem occurs and the generation of Back arrows appears to be a bit random, especially in document apps. I have found it well worth making the effort to use NavigationSplitView and NavigationStack, even though this has involved me writing quite a lot of extra code to achieve pleasing results, particularly in apps designed to run at their best on both iPhone and iPad. That said, Apple do provide some clear advice on how to adopt the new Views here.

I have come across another oddity with iOS 16. Pickers in modal sheets, which have their list arrays populated .onAppear, no longer work as intended and the Picker selection can no longer be set programmatically. You have to populate the Picker's list before activating the modal sheet and pass it to the Sheet as a Binding.

Thanks halo for a top tip on how to use if #available().

Aluin answered 9/10, 2022 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.