How to add scope buttons in a UISearchController e

2019-03-06 10:46发布

问题:

I have an App that is presenting a MKMapView embedded in a UINavigationController. In the UINavigationController I have put a UISearchController. When the User touch the UISearchController it displays a UITableViewController. It works well while I'm not adding the Scope button in the UISearchController.

Here the screenshot of the UISearchController in the UINavigationController when I start the App.

Next when I touch the UISearchController, it displays the UITableViewController and scope button.

Here we can already see there's an issue with the scope button because they are not well integrated in the UISearchController (color should be translucent)

Next, when I touch the Cancel button to go back to the Main viewController, the UISearchController is not recovering its original style

it has a dark gray border (that probably comes from the scope button).

Here's how I add the UISearchController in the Main view Controller

    func initSearchController() {
    let mySearchController = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchControllerId") as! SearchController

    self.searchController = UISearchController(searchResultsController: mySearchController)

    mySearchController.theSearchController = self.searchController
    mySearchController.delegate = self

    // Configure the UISearchController
    self.searchController.searchResultsUpdater = self
    self.searchController.delegate = self

    self.searchController.searchBar.delegate = self
    self.searchController.searchBar.placeholder = "data.." 
    self.searchController.hidesNavigationBarDuringPresentation = false
    self.searchController.dimsBackgroundDuringPresentation = true

    self.navigationItem.titleView = searchController.searchBar

    self.definesPresentationContext = true


}

this method is called in the viewDidLoad() of my Main ViewController.

Next, when the SearchController is displayed, I'm adding the scope button with the following code in my TableViewController subclass

    override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    // Mandatory to make sure the TableView is displayed when the search field is empty
    // when user touch it.
    view.hidden = false

    var rect = delegate.searchController.searchBar.superview?.frame
    rect?.size.height = 88

    self.delegate.searchController.searchBar.scopeButtonTitles = ["one", "two", "three"]
    self.delegate.searchController.searchBar.showsScopeBar = true
    self.delegate.searchController.searchBar.superview?.frame = rect!
}

and the following code is executed when search is closed

    override func viewDidDisappear(animated: Bool) {
    super.viewDidDisappear(animated)


    var rect = delegate.searchController.searchBar.superview?.frame
    rect?.size.height = 44

    self.delegate.searchController.searchBar.superview?.frame = rect!
    self.delegate.searchController.searchBar.showsScopeBar = false
    self.delegate.searchController.searchBar.scopeButtonTitles = nil
}

As you can see I have severals issues with this code.

  1. Scope buttons are not displayed correctly and I'm unable to add them with a nice animation
  2. When user exits the search Scope buttons are removed but it impacts the background of the UISearchController

Can you tell me what I'm doing wrong and what should I do to integrate correctly Scope Button in UISearchController?. I have found examples but only when the UISearchController is not embedded in the UINavigationController.

Thanks for your help!

Sébastien.

回答1:

You should try using the searchBar.scopeButtonTitles in your instance of UISearchController:

func initSearchController() {
   let mySearchController = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchControllerId") as! SearchController

    searchController = UISearchController(searchResultsController: mySearchController)

    // Set Scope Bar Buttons
    searchController.searchBar.scopeButtonTitles = ["one", "two", "three"]
//    searchController.searchBar.showsScopeBar = true //if you want it always visible

    // Configure the UISearchController
    searchController.searchResultsUpdater = self
    searchController.searchBar.sizeToFit()
    tableView.tableHeaderView = searchController.searchBar

    searchController.delegate = self
    searchController.searchBar.delegate = self
    searchController.searchBar.placeholder = "data.." 
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.dimsBackgroundDuringPresentation = true

    definesPresentationContext = true
}

No need to show or hide your scopeButtons in willAppear/didDisapear. This is set by: searchController.searchBar.showsScopeBar = true