Cancelling search with UISearchController causes crash

依然范特西╮ 提交于 2019-12-10 07:02:50

问题


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


回答1:


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;
}



回答2:


Try cleaning all your references as given below.

-(void)dealloc{
    if (_searchController) {
        _searchController.searchResultsUpdater = nil;
        _searchController.searchBar.delegate = nil;
        _searchController.delegate = nil;
    }
}



回答3:


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



来源:https://stackoverflow.com/questions/36834755/cancelling-search-with-uisearchcontroller-causes-crash

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!