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.

Post not yet marked as solved Up vote post of YK_L Down vote post of YK_L
8k views
  • Also this only happening on device. When running on simulator it is all fine

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

  • 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.

Add a Comment

Replies

Im seeing this too.

  • Did you find any workaround?

  • No

  • I've been struggling with this issue as wel. In my case, it encounters when I switch out one view with a NavigationView with another one. This code worked perfectly on iOS 15 devices.

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 assume your app is targeting iOS 16+. If you need to support iOS 15 you will need to have 2 sets of code 1 for iOS 15 using NavigationView and 1 for iOS 16 using NavigationStack?

Add a Comment

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 :/

  • I'm able to get it crash on device a couple of times with debugger attached but it does not get caught with any breakpoint and nothing useful with the stack trace...

Add a Comment

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?

  • Depending how you present the .sheet just call the code before you set the binding of isPresented to false or set the binding Item to nil

Add a Comment

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.

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)

  • This solved my problem. Thank you so much.

  • This is working for me but hard to handle the navigation links with navigationStack. Thank you so much.

Add a Comment

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