Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS UISearchController crash: Application tried to present modal view controller on itself

According to crashlytics the following crash is occurring (rarely).

Application tried to present modal view controller on itself. Presenting controller is .

I can't replicate this issue at all. This is how I setup my UISearch Controller.

    self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    self.searchController.dimsBackgroundDuringPresentation = NO;
    self.searchController.searchBar.delegate = self;

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

Any help is appreciated because I am all out of ideas. I will post more code if needed.

like image 712
Curt Rand Avatar asked Oct 24 '17 18:10

Curt Rand


3 Answers

Make sure you use

self.searchController = UISearchController()

instead of

self.searchController = UISearchController(searchResultsController: self)
like image 145
Christo Smal Avatar answered Sep 17 '22 21:09

Christo Smal


I had that issue when I updated to iOS 11. My scenario was, that I had a Textfield, and when the user started to edit that, a search-view, essentially a tableview with a searchbar as header popped up and once a tableview cell was tapped it should close.

The problem seems to be that since iOS 11, the OS tries to restore the firstResponder state. Long story short.

It helped when I added active = NO, to my did select method, like so

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
   self.searchController.active = NO; // Add this !
   ...

   [self dismissViewControllerAnimated:YES completion:nil];
}
like image 45
Kastor Avatar answered Sep 19 '22 21:09

Kastor


If you're like me and needed the searchController to remain active while presenting modally another controller, then do the following to get the same effect of presenting modally without doing so directly:

Quick note: Not familiar enough with Obj-C to give an answer in that, but here's an answer in Swift 4. Someone feel free to edit and add Obj-C if necessary, but I think it's clear here how to solve the issue at-hand, even if it is in Swift.

Let's say I have a menu that I want to pop-up:

let info = the info you need to pass
let currVC = self.getTopMostViewController()
let menuVC = currVC.storyboard?.instantiateViewController(withIdentifier: "myStringIdentifierSetInStoryboard") as? EventMenuViewController
guard menuVC != nil else { return }
menuVC!.info = info // Pass info necessary (i.e. what you would normally pass in prepare(for segue: ...). menuVC.info is a global variable from your class
currVC.present(menuVC!, animated: true, completion: nil)

The implementation of getTopMostViewController() may vary. Mine is below and is adapted from here.

func getTopMostViewController() -> UIViewController {
    let anyVC = UIViewController()
    if var topController = UIApplication.shared.keyWindow?.rootViewController {
        while let presentedViewController = topController.presentedViewController {
            topController = presentedViewController
        }
        return topController
    }
    return anyVC
}

Hope this helps! This does not give you the error described for iOS 12 and Swift 4, although I did get that exact error when trying to present modally with an active search controller, which is what led me here.

like image 43
Joshua Wolff Avatar answered Sep 17 '22 21:09

Joshua Wolff