iosuitabbarcontrollerios11uisearchcontrollerpreferslargetitles

UISearchController with large titles crashes in Tab bar with "Only one palette with a top boundary edge can be active outside of a transition"


I have multiple tabs in a UITabBarController. All of them have a UINavigationBar with large titles and a iOS-11-built-in-search-bar. However, switching between the tabs makes the app crash with

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'Only one palette with a top boundary edge can be active outside of a transition. Current active palette is 
<_UINavigationControllerManagedSearchPalette: 0x7fc399b49980; frame = (0 96; 375 52); layer = <CALayer: 0x60c0004383a0>>'

I've tested the workaround posted here: https://stackoverflow.com/a/46382723/511299 without success. This question did not use a UITabBarController.

I've added this code to viewDidAppear:

DispatchQueue.main.async {
    let searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self
    self.navigationItem.searchController = searchController
}

and this to viewWillDisappear:

self.navigationItem.searchController = nil

Adding prints to each method to check the order verifies that is nils out the previous view before setting it on the appearing view.

It crashes after going from tab 0 to tab 1, then back to tab 0. I do not even need to scroll down to show the searchbar.

Full stack trace:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Only one palette with a top boundary edge can be active outside of a transition. Current active palette is <_UINavigationControllerManagedSearchPalette: 0x7fea7dcaf880; frame = (0 44; 375 52); layer = <CALayer: 0x60000062ac20>>'
*** First throw call stack:
(
0   CoreFoundation                      0x000000010b8381e6 __exceptionPreprocess + 294
1   libobjc.A.dylib                     0x0000000109cda031 objc_exception_throw + 48
2   CoreFoundation                      0x000000010b8ad975 +[NSException raise:format:] + 197
3   UIKit                               0x000000010e67dec6 -[UINavigationController(_UIPalette) attachPalette:isPinned:] + 521
4   UIKit                               0x000000010e659afd -[UINavigationController _createAndAttachSearchPaletteForTopViewControllerIfNecessary:] + 585
5   UIKit                               0x000000010e677c10 -[UINavigationController _navigationItemDidUpdateSearchController:oldSearchController:] + 419
6   UIKit                               0x000000010f0737a1 -[_UINavigationBarVisualProviderModernIOS navigationItemUpdatedSearchController:oldSearchController:animated:] + 160
7   UIKit                               0x000000010edf15c4 -[UINavigationItem setSearchController:] + 135
8   Appmost                             0x0000000107e5902e _T07Appmost25JsonCreatedViewControllerC14setupSearchBaryyFyycfU_ + 1486
9   Appmost                             0x0000000107e590cd _T07Appmost25JsonCreatedViewControllerC14setupSearchBaryyFyycfU_TA + 13
10  Appmost                             0x0000000107cbcb7d _T0Ieg_IeyB_TR + 45
11  libdispatch.dylib                   0x00000001124c97ab _dispatch_call_block_and_release + 12
12  libdispatch.dylib                   0x00000001124ca7ec _dispatch_client_callout + 8
13  libdispatch.dylib                   0x00000001124d58cf _dispatch_main_queue_callback_4CF + 628
14  CoreFoundation                      0x000000010b7fac99 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
15  CoreFoundation                      0x000000010b7beea6 __CFRunLoopRun + 2342
16  CoreFoundation                      0x000000010b7be30b CFRunLoopRunSpecific + 635
17  GraphicsServices                    0x0000000113adaa73 GSEventRunModal + 62
18  UIKit                               0x000000010e482057 UIApplicationMain + 159
19  Appmost                             0x0000000107f72167 main + 55
20  libdyld.dylib                       0x0000000112547955 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSExceptio

Solution

  • I have tried to recreate the issue but everything seems fine when I added the code in func viewDidLoad()

    Below is the code for adding search view controller in iOS11

        if #available(iOS 11.0, *) {
            //Setup Search Controller
            self.searchController.obscuresBackgroundDuringPresentation = false
            self.searchController.searchBar.placeholder = "Search"
            self.searchController.searchBar.barStyle = .black
            self.searchController.searchBar.delegate = self
            self.definesPresentationContext = true
            self.navigationItem.searchController = searchController
            self.navigationItem.title = "Heading 2"
        }
    

    I have also created a demo project for you please find it in Github Here