iOS 16 crash on dismiss sheet with navigationView

Hi, I've recently experienced a weird crash that only happening on iOS 16 device. When dismiss a sheet which contains NavigationView it sometime crashes. It is not 100% reproducible but relatively easy to get crash. The same build running on iOS 15 device is totally fine. The crash report shows nothing useful and the stack trace shows none of my code so I'm not sure what's going on in here. Any help is much appreciated.

Also this only happening on device. When running on simulator it is all fine

I've also set the navigationViewStyle to be StackNavigationViewStyle()

Im seeing this too.

I have the exact same issue.

The last lines of the log are always the same

Thread 0 name:   Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   SwiftUI                       	       0x1b8f98208 0x1b8781000 + 8483336
1   SwiftUI                       	       0x1b8f981c8 0x1b8781000 + 8483272
2   SwiftUI                       	       0x1b8f98220 0x1b8781000 + 8483360
3   SwiftUI                       	       0x1b99ddbc4 0x1b8781000 + 19254212
4   SwiftUI                       	       0x1b87e9244 0x1b8781000 + 426564
5   SwiftUI                       	       0x1b87c8dd0 0x1b8781000 + 294352
6   UIKitCore                     	       0x1b7171c84 -[UIViewController removeChildViewController:notifyDidMove:] + 128
7   UIKitCore                     	       0x1b7735f7c -[UINavigationController removeChildViewController:notifyDidMove:] + 80
8   UIKitCore                     	       0x1b71bfa10 -[UIViewController dealloc] 

I found a solution for this. I replaced all my NavigationViews with NavigationStacks.

I literally have the same issue. It most likely happens when I close the modal screen.... Unfortunately, this is a huuuge problem that does not occur on iOS <16 The worst part is that it is not easily reproducible :/ It just sometimes occurs, good luck debugging that :/

Yes but this did not fix the problem 100% it seems to be worse on iOS 16 and better in iOS 16.2.

I've found a workaround which can prevent this crash from happening.

if #available(iOS 16.0, *) {
            let keyWindow = UIApplication.shared.connectedScenes
              .filter { $0.activationState == .foregroundActive }
              .first(where: { $0 is UIWindowScene })
              .flatMap { $0 as? UIWindowScene }?.windows
              .first(where: \.isKeyWindow)

            if let window = keyWindow {
              window.rootViewController?.presentedViewController?.dismiss(animated: true)
            }
}

Using UIKit to dismiss the model seem to work fine and won't trigger the crash. But this is not ideal and I don't know when this can get fixed.

Where are you putting this code? Are you writing an extension into View?

I had the same problem except it happened when calling dismiss on a PresentationMode in SwiftUI. FWIW scheduling it on the next RunLoop worked for me:

RunLoop.main.schedule {
    self.presentationMode.wrappedValue.dismiss()
}

For the record, I am also seeing this crash when dismissing a navigationView with pushes views. Very frustrating!

I'm also seeing this, when changing SwiftUI state such that a navigation view with a pushed view now no longer exists. The comments in this thread helped me find a workaround: dismiss the pushed view and then carry out the actions that update the state. Thanks everyone!

Oh, forgot to mention I'm also seeing this only on iOS 16.0.3, not 15.

Hey @davberk, would you be able to share your solution? I am facing the same issue and for now I solved it by using bottom sheet to present a screen, but I don't really like it UX/UI wise.

I just don't think SwiftUI's state-driven design will ever be able to reliably manipulate UIKit's event-driven navigation components like UINavigationController and UISplitViewController. Especially because these have some of their own adaptive behaviour that will undermine the SwiftUI state. We probably need new versions of these components with all their hacks removed.

Here's a work around that is working for me.

struct NavStackWorkaround<T: View>: View {
  let content: ()->T
   
  var body: some View {
    if #available(iOS 16, *) {
      NavigationStack(root: content)
    } else {
      NavigationView(content: content)
        .navigationViewStyle(.stack)
    }
  }
}

Simply replace your NavigationView uses with NavStackWorkaround (and remove the .navigationViewStyle)

Hi, your workaround works but the navigationLinks (with isActive param) are not working Actually They are working once. It is like the state is not set again when you goback previous screen

I am experiencing this crash, but we use UIKit navigation with HostViewControllers + SwiftUI Views on them. Any thoughts on workarounds? Thanks

We found this issue on certain iPhones running iOS 16 and in the end we realised we had a function written like so:

// Bad code!
fun doButtonAction() {
    DispatchQueue.main.async { [weak self] in
        self?.sheetItem = .none
    }
}

// SwiftUI View below
Button {
    doButtonAction()
} label : {
   Text("Press me!")
}

And what fixed it for us was:

@MainActor fun doButtonAction() {
    sheetItem = .none
}

The same crash occured in the app i'm working on. Only on iOS 16. It seems like the reason for the crash is pushing a new view before the last view dismisses. In my case, it was dismissing a fullscreen cover and changing a tab in a tabview. Workaround that worked for me was, Dismiss the cover view, and it's onDisappear change the tab. (Keep a state variable so tab change doesnt happen in every onDisappear)

iOS 16 crash on dismiss sheet with navigationView
 
 
Q