Cancelling search with UISearchController causes crash
Asked Answered
S

3

4

In our app we have a UITableViewController that has a UISearchController:

searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
[self.searchController.searchBar sizeToFit];

self.tableView.tableHeaderView = self.searchController.searchBar;
self.showFooterView = YES;

self.searchController.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = NO; // default is YES
self.searchController.searchBar.delegate = self;
self.definesPresentationContext = YES;

The table view controller is also a UISearchBarDelegate and UISearchControllerDelegate.

#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [searchBar resignFirstResponder];
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    self.contacts = self.allContacts;
    [self.tableView reloadData];
}

Now everything works as expected, but there are occasions when a user starts a search, types in a few characters in the search bar, results are returned, and the user cancels the search and then this happens:

Fatal Exception: NSInvalidArgumentException
-[_UIFullscreenPresentationController adaptivePresentationController]: unrecognized selector sent to instance 0x147c81ce0

Fatal Exception: NSInvalidArgumentException
0  CoreFoundation                 0x1842b4f48 __exceptionPreprocess
1  libobjc.A.dylib                0x198d77f80 objc_exception_throw
2  CoreFoundation                 0x1842bbc5c __methodDescriptionForSelector
3  CoreFoundation                 0x1842b8c00 ___forwarding___
4  CoreFoundation                 0x1841bccac _CF_forwarding_prep_0
5  UIKit                          0x18a1ba084 -[UISearchController _searchPresentationController]
6  UIKit                          0x189e7d10c -[_UISearchControllerTransplantSearchBarAnimator animateTransition:]
7  UIKit                          0x189b9fa90 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke
8  UIKit                          0x189af856c _runAfterCACommitDeferredBlocks
9  UIKit                          0x189b054bc _cleanUpAfterCAFlushAndRunDeferredBlocks
10 UIKit                          0x189839984 _afterCACommitHandler
11 CoreFoundation                 0x18426bbd0 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
12 CoreFoundation                 0x184269974 __CFRunLoopDoObservers
13 CoreFoundation                 0x184269da4 __CFRunLoopRun
14 CoreFoundation                 0x184198ca0 CFRunLoopRunSpecific
15 GraphicsServices               0x18f3d4088 GSEventRunModal
16 UIKit                          0x1898b0ffc UIApplicationMain

We have never been able to reproduce this error, although it gets reported by Fabric on production.

This problem looks similar to this: Selecting cell after search doesn't segue visually, but loads next view Swift Xcode but no real answer has been given there yet.

I have started looking into presentation controllers but we have no special functionality that would require setting up presentation controllers in a specific way.

Any ideas on how to fix this?

Thanks

Scarify answered 25/4, 2016 at 7:50 Comment(1)
did you found the answer. or still you are facing the issue. Sure this issue with your code level. you are trying to access but that was not in memoryAcuity
A
3

I've faced the same problem on Swift.

The problem is Searchbarcontroller still hold the reference(delegate) of your ViewController.

So all you have to do is manually remove the reference when view dealloc or disappear

Something like this:

- (void)dealloc {
    self.searchController.searchResultsUpdater = nil;
    self.searchController.searchBar.delegate = nil;
    self.searchController.delegate = nil;
    self.searchController = nil;
}
Amyloid answered 15/5, 2016 at 16:42 Comment(0)
C
0

Try cleaning all your references as given below.

-(void)dealloc{
    if (_searchController) {
        _searchController.searchResultsUpdater = nil;
        _searchController.searchBar.delegate = nil;
        _searchController.delegate = nil;
    }
}
Cerellia answered 10/8, 2016 at 6:20 Comment(1)
no need for the _searchController check, as else the remaining code runs on nil, also you don't need to refer to the ivar, but can safe use the self.getterSaid
B
0

Utilize UISearchContainerViewController as Main ViewController and wrap your SearchController inside it.

A view controller that manages the presentation of search results in your interface.

Although you can present a search controller object modally, you should never push one onto a navigation controller’s stack or use one as a child of another container view controller. Instead, embed an instance of this class and let it manage the presentation of the search controller’s content.

https://developer.apple.com/documentation/uikit/uisearchcontainerviewcontroller

Barde answered 8/10, 2019 at 15:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.