Home > Mobile >  SwiftUI - iOS - Using scenePhase causes views to pop when app going to background and back to active
SwiftUI - iOS - Using scenePhase causes views to pop when app going to background and back to active

Time:05-15

I have a project and I am trying to implement scenePhase. The logic of the implementation seems to work fine, but I have the following strange problem. When an iOS (and Android also) app goes to the background, and then is tapped again, it is expected to go to the last screen shown. This happens, but when i declare (not even use) the Environment var "scenePhase", when I put my app in the background and then activate it again, it shows the next-to-the-declaration screen. Let me be clear with some code (simplified compared to my app, but the behavior is present here too):

First view:

import SwiftUI

struct ContentView: View {
    
    @State var actionState: Int? = 0
    @Environment(\.scenePhase) private var scenePhase
    
    var body: some View {
        NavigationView{
            NavigationLink(destination: View2(), tag: 1, selection: $actionState, label: {
                Button(action: {
                    actionState = 1
                }, label:{
                    Text("Hello, world! 1 ")
                        .padding()
                })
            })
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Second View:

import SwiftUI

struct View2: View {
    var body: some View {
        NavigationLink(destination: View3()){
            Text("Hello, world! 2 ")
                .padding()
        }
    }
}

struct View2_Previews: PreviewProvider {
    static var previews: some View {
        View2()
    }
}

Third View:

import SwiftUI

struct View3: View {
    var body: some View {
        Text("Hello, World! 3")
    }
}

struct View3_Previews: PreviewProvider {
    static var previews: some View {
        View3()
    }
}

If I follow the clicks, and go all the way to the third view, when I put the app in the background and then to the foreground again, instead of the third, it shows the second view. If I delete this declaration: @Environment(\.scenePhase) private var scenePhase it shows (correctly) the third view. Any help is appreciated!!!

CodePudding user response:

The scenePhase change causes body to be called to recompute the View hierarchy and you can't have more than one detail NavigationLink so you need to set the second to isDetailLink(false).

And by the way you don't need a Button inside the NavigationLink because it will render a suitable tappable thing like a button or table row itself.

  • Related