In SwiftUI, the application freeze without any warning when slide back halfway but released before completion

Viewed 1098

The following code reproduced the error:

import SwiftUI

struct ContentView: View {
    @State private var number: Int = 5
    var body: some View {
        NavigationView() {
            VStack(spacing: 20) {
                NavigationLink(destination: SecondView(bottles: $number)) {
                    Text("Click me")
                }
            }
        }
    }
}

struct SecondView: View {
    @Environment(\.presentationMode) private var presentationMode: Binding<PresentationMode>
    @State private var color: UIColor = .black
    @Binding var bottles: Int

    var body: some View {
        Text("I have \(bottles) in my bag")
            .foregroundColor(Color(color))
            .navigationBarTitle(Text("Water Bottle"))
            .navigationBarItems(trailing:
                Button("Click") {
                    self.someFunction()
                }
        )
    }

    func someFunction() {
        if self.color == UIColor.black {
            self.color = .red
        } else {
            self.color = .black
        }
    }
}

When sliding back from SecondView to ContentView but didn't complete the gesture, the app freezes. When deleting either @Environment or NavigationBarItem will fix this error.

For @Environment, it is needed for CoreData but used presentationMode for reproduction of error

1 Answers

adding ".navigationViewStyle(StackNavigationViewStyle())" to the NavigationView fix the problem for me. This is the code I use for testing this on real devices (iPhone, iPad) and various simulators. Using macos 10.15.5, Xcode 11.5 and 11.6 beta, target ios 13.5 and mac catalyst.

I have not tested this on all devices, so let me know if you find a device where this does not work.

import SwiftUI

struct ContentView: View {
@State private var number: Int = 5
var body: some View {
    NavigationView() {
        VStack(spacing: 20) {
            NavigationLink(destination: SecondView(bottles: $number)) {
                Text("Click me")
            }
        }
    }.navigationViewStyle(StackNavigationViewStyle())  //  <---
}
}

struct SecondView: View {
@Environment(\.presentationMode) private var presentationMode: Binding<PresentationMode>
@State private var color: UIColor = .black
@Binding var bottles: Int

var body: some View {
    Text("I have \(bottles) in my bag")
        .foregroundColor(Color(color))
        .navigationBarTitle(Text("Water Bottle"))
        .navigationBarItems(trailing:
            Button("Click") {
                self.someFunction()
            }
    )
}

func someFunction() {
    if self.color == UIColor.black {
        self.color = .red
    } else {
        self.color = .black
    }
}
}
Related