Reputation: 531
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
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(_:))
}
Upvotes: 0
Views: 4440
Reputation: 5451
self.searchController.dismissViewControllerAnimated(true, completion: nil)
Upvotes: 1
Reputation: 531
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(_:))
}
Upvotes: 1
Reputation: 9150
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()
}
Upvotes: 2