4

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
Sunkas
  • 9,542
  • 6
  • 62
  • 102
  • Do you get this crash while switching from a tab with active search? – cocavo Aug 13 '18 at 15:57
  • try this searchController.isActive = false – guru Aug 14 '18 at 05:19
  • Added description to reproduce to the question – Sunkas Aug 14 '18 at 08:00
  • @guru Adding `searchController.isActive = false` in viewWillDisapperar does not help. – Sunkas Aug 14 '18 at 08:02
  • @Sunkas Does every tab have it's own `UINavigationController` or your `UITabBarController` is embedded into `UINavigationController`? Also a whole stack trace of the crash would be very helpful. – cocavo Aug 14 '18 at 15:21
  • Yes, every tab has it's own `UINavigationController`. It would be weird otherwise. Will attach a full stack trace to question! – Sunkas Aug 16 '18 at 14:46
  • 1
    @Sunkas I have created a sample project for reproducing the issue but unfortunately it is not recreated Could you please have look on this https://github.com/Arunjos/TabBarWithSearchViewController – arunjos007 Aug 19 '18 at 16:31
  • @arunjos007 You forgot to enable largeTitles, and calling super in viewDidDissappear. But your code seems to work otherwise. Placing the code in viewDidAppear reproduces it though. I also need to dynamically hide/show the searchbar as a feature. But perhaps this can be done in other places than viewWillAppear. Will get back to you how your solution worked. – Sunkas Aug 20 '18 at 08:43
  • @Sunkas updated the repo with changes but seems works fine here, anyway please check and let me know – arunjos007 Aug 20 '18 at 10:40
  • @arunjos077, write this as an answer before it expires (1 hour) and I'll award you the bounty. The answer was to just setup the search-bar in `viewDidLoad` instead of `viewDidAppear` – Sunkas Aug 20 '18 at 13:07
  • @Sunkas Okay thanks! I have added it as answer – arunjos007 Aug 20 '18 at 15:47

3 Answers3

3

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

arunjos007
  • 4,105
  • 1
  • 28
  • 43
  • The main issue seems to be unloading and loading again in viewDidDissappear/viewDidAppear. Setting up the searchbar in viewDidLoad did work just fine. Must have been some other issue before that made me move away from this approach. – Sunkas Aug 21 '18 at 04:17
0

I have added this code in viewDidLoad() and it's working

Try to add this line of code:

searchController.dimsBackgroundDuringPresentation
shiju86.v
  • 667
  • 5
  • 10
0

These lines solved my problem.

let search = UISearchController(searchResultsController: nil)
    search.obscuresBackgroundDuringPresentation = false
    self.definesPresentationContext = true
Zain Ul Abideen
  • 693
  • 10
  • 15