Crashing when going from Compact to Two Over Secondary in UISplitViewController on iPadOS 17

I have been struggling with a crash bug that begin popping up in iPadOS 17 when we moved our app over to building under Xcode 15. It is important to note that the prior release, built under Xcode 14 works fine. Also, the crash does not occur in versions of iPadOS prior to iPadOS 17, even when built under Xcode 15.

The main view controller is a UISplitView that has primary, secondary, and supplemental views. Each, hosted in a UINavigationController. The primary view has the navigation bar hidden (this is important).

If the supplemental view has an additional view controller pushed onto the navigation stack, hence a back button is being shown in the middle navigation controller, and the app is transitioned to a compact size class (secondary controller shown at the top of the stack) and then transitions back to a regular size class, we get a crash with the following:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Layout requested for visible navigation bar, <UINavigationBar: 0x1038e3a40; frame = (0 -102; 834 102); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x600000d586f0>; layer = <CALayer: 0x6000003690e0>> delegate=0x105809800 standardAppearance=0x600002662940 scrollEdgeAppearance=0x600002661620, when the top item belongs to a different navigation bar. topItem = <UINavigationItem: 0x103b2bb10> titleView=0x1039b1a70 style=navigator rightBarButtonItems=0x6000000427e0 largeTitleDisplayMode=never searchController=0x1068c1a00 preferredSearchBarPlacement=stacked, navigation bar = <UINavigationBar: 0x103b452c0; frame = (0 24; 834 102); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x600000cd7d20>; layer = <CALayer: 0x600000316700>> delegate=0x104898400 standardAppearance=0x60000265ea00 scrollEdgeAppearance=0x60000265fd80, possibly from a client attempt to nest wrapped navigation controllers.' *** First throw call stack: ( 0 CoreFoundation 0x0000000180491128 __exceptionPreprocess + 172 1 libobjc.A.dylib 0x000000018008412c objc_exception_throw + 56 2 Foundation 0x0000000180d1163c _userInfoForFileAndLine + 0 3 UIKitCore 0x00000001848d2510 -[UINavigationBar layoutSubviews] + 472 4 UIKitCore 0x0000000185806d78 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1492 5 UIKitCore 0x00000001848d21d8 -[UINavigationBar layoutSublayersOfLayer:] + 188 6 QuartzCore 0x0000000189ffa5b0 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 440 7 UIKitCore 0x00000001857f6260 -[UIView(Hierarchy) layoutBelowIfNeeded] + 292 8 UIKitCore 0x0000000184b147f8 -[UINavigationController _positionNavigationBarHidden:edge:initialOffset:] + 584 9 UIKitCore 0x0000000184b149b0 -[UINavigationController _positionNavigationBarHidden:edge:] + 264 10 UIKitCore 0x0000000184b163dc __64-[UINavigationController _setNavigationBarHidden:edge:duration:]_block_invoke + 404 11 UIKitCore 0x0000000184b1603c -[UINavigationController _setNavigationBarHidden:edge:duration:] + 488 12 UIKitCore 0x0000000184b14518 -[UINavigationController setNavigationBarHidden:animated:] + 92

However, if we do not hide the navigation bar in the primary view: no crash. Likewise, if there isn't a second controller pushed onto the navigation stack (meaning no back button is shown), there is no crash, even if the navigation bar is hidden in the primary view.

This structure has been fine for over three years and the problem only began with iPadOS 17 building under Xcode 15.

I have found similar mentions on other forums, but no real solution.

I realize I should probably file a feedback. Unfortunately, past experience has shown that it is a good way to waste countless hours gathering information, creating sample projects that distill the bugs down to their core, only to be met with complete and utter silence. I've lost all confidence in that system and I'm hoping someone else who has run into this may have a workaround or at least some suggestions for things to try.

Answered by Enderlyn in 778081022

In case this helps anyone who stumbles across this, I was able to fix the problem by using the isNavigationBarHidden property instead of the setNavigationBarHidden method (the method failed regardless of whether the animated parameter was set to true or false).

Accepted Answer

In case this helps anyone who stumbles across this, I was able to fix the problem by using the isNavigationBarHidden property instead of the setNavigationBarHidden method (the method failed regardless of whether the animated parameter was set to true or false).

This is something I've been struggling with for some time.

The hierarchy of my app makes this harder to diagnose. But like you, it was working fine for years. In my case, this app supported three column-layouts prior to the release of column-based split views. In order to do so, we have a concept of a NestedSplitViewController -- which is a UIViewController that owns a UISplitView.

We're running into the same issue with Xcode 15 – and can't seem to pin it down.

We are seeing the same error when trying to hide toolbar in a view inside NavigationSplitView on iPhone 16 Pro Max simulator running iOS 18. This crashes when rotating the phone to landscape when the view is open and toolbar hidden.

We would sometimes want to hide the toolbar in compact mode, but haven't found a good solution yet.

import SwiftUI

enum NavigationDestination: Hashable, Codable {
  case home
}

struct ContentView: View {
  @State var columnVisibility: NavigationSplitViewVisibility = .all
  @State var navigationPath: [NavigationDestination] = []

  @ViewBuilder
  var sidePanel: some View {
    VStack {
      Button("Home") {
        navigationPath.append(.home)
      }
    }
  }

  var body: some View {
    ZStack {
      NavigationSplitView(
        columnVisibility: $columnVisibility,
        sidebar: {
          sidePanel
        },
        detail: {
          NavigationStack(path: $navigationPath) {
            ZStack {}
              .navigationDestination(for: NavigationDestination.self) { d in
                switch d {
                case .home:
                  HomeView()
                }
              }
          }
        }
      )
    }
  }
}

struct HomeView: View {
  var body: some View {
    VStack {
      Text("Home view")
    }
    .toolbar(.hidden)
  }
}
Crashing when going from Compact to Two Over Secondary in UISplitViewController on iPadOS 17
 
 
Q