简体   繁体   中英

Swift - Dismiss search controller

I'm currently trying to implement a search functionality over a UITableView with dynamic data retrieved from an API call.

The flow would be something like this

  1. Press the right bar button item (search functionality)
  2. A search controller is presented over the table view.
  3. The user enters some text on it and presses the search button
  4. The controller performs an API call based on the user's search.
  5. The table view gets populated with the results.

I've seen sokme examples on how to implement search over a tableView, and I think mine is different, because I manually present the search controller. It's not shown until the search button is pressed (as opossite to the examples, when UISearch is added to table header view and the search functionality is triggered when the user taps over the search bar.)

So basically I've got some questions:
1.- Is my approach iOS-friendly? Maybe I cannot find resources about how I'm trying to achieve because It's not.
2.- If true, how can I dismiss the search controller after the search button on the keyboard is pressed?
3.- How can I distinguish between a dismissal fired by the search button on keyboard or by the cancel button on search bar?

Here's my code so far:

extension MyTableViewController: UISearchResultsUpdating {
  func updateSearchResultsForSearchController(searchController: UISearchController) {
  }
}

class MyTableViewController: UITableViewController, UISearchControllerDelegate {
  var searchController: UISearchController!
  var data = [CoolData]()

  override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "search"), style: .Plain, target: self, action: .SearchTapped)
  }

  func searchButtonTapped(sender: UIBarButtonItem) {
    searchController = UISearchController(searchResultsController: nil)
    definesPresentationContext = true
    searchController.searchResultsUpdater = self
    searchController.delegate = self
    searchController.searchBar.translucent = false
    searchController.searchBar.barTintColor = UIColor(hexString: BACConstants.color.Yellow)
    searchController.searchBar.tintColor = UIColor(hexString: BACConstants.color.Black)
    self.presentViewController(searchController, animated: true, completion: nil)
  }

}

private extension Selector {
  static let SearchTapped = #selector(InvolvedProcessesViewController.searchButtonTapped(_:))
}

assuming you are using UITableViewController , you can add a UISearchController like this:

var shouldShowSearchResults = false
var searchController: UISearchController!

func configureSearchController() {
    searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false
    searchController.searchBar.delegate = self
    searchController.searchBar.sizeToFit()

    tableView.tableHeaderView = searchController.searchBar
}

then, implement this two delegates: UISearchResultsUpdating , UISearchBarDelegate

 // MARK: - UISearchBarDelegate

func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
    // do your thing
}

func searchBarCancelButtonClicked(searchBar: UISearchBar) {
    // do your thing
}

func searchBarSearchButtonClicked(searchBar: UISearchBar) {
    // do your thing
    searchController.searchBar.resignFirstResponder()
}

// MARK: - UISearchResultsUpdating

func updateSearchResultsForSearchController(searchController: UISearchController) {
    let searchString = searchController.searchBar.text!.lowercaseString

    // do your thing..

    tableView.reloadData()
}

Taking @matias-elorriaga answer I've finally made it. I was using the wrong delegate to handle my search events.

extension MyTableViewController: UISearchResultsUpdating {
  func updateSearchResultsForSearchController(searchController: UISearchController) {
  }
}

class MyTableViewController: UITableViewController, UISearchBarDelegate {
  var searchController: UISearchController!
  var data = [CoolData]()

  override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "search"), style: .Plain, target: self, action: .SearchTapped)
  }

  func searchButtonTapped(sender: UIBarButtonItem) {
    searchController = UISearchController(searchResultsController: nil)
    definesPresentationContext = true
    searchController.searchResultsUpdater = self
    searchController.delegate = self
    searchController.searchBar.translucent = false
    searchController.searchBar.barTintColor = UIColor(hexString: BACConstants.color.Yellow)
    searchController.searchBar.tintColor = UIColor(hexString: BACConstants.color.Black)
    self.presentViewController(searchController, animated: true, completion: nil)
  }    

  func searchBarTextDidEndEditing(searchBar: UISearchBar) {
    // Do stuff
  }

  func searchBarCancelButtonClicked(searchBar: UISearchBar) {
    // Do stuff
  }

  func searchBarSearchButtonClicked(searchBar: UISearchBar) {
    self.searchController.dismissViewControllerAnimated(true, completion: nil) // When search is tapped, dismiss the search and fetch the results based on the filter 
  }
}

private extension Selector {
  static let SearchTapped = #selector(InvolvedProcessesViewController.searchButtonTapped(_:))
}
self.searchController.dismissViewControllerAnimated(true, completion: nil)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM