UISearchBar and UISearchBarDelegate
UISearchBar and UISearchBarDelegate
One of the most important feature in an iOS application would be searching functionality, today we will be learning how to add search to our tableview application in Swift using UISearchBar and UISearchBarDelegate
UISearchBar
The UISearchBar class implements a text field control for text-based searches. The control provides a text field for entering text, a search button, a bookmark button, and a cancel button. The UISearchBar object does not actually perform any searches. You use a delegate, an object conforming to the UISearchBarDelegate protocol, to implement the actions when text is entered and buttons are clicked. You can hide and show the cancel button by setting `showsCancelButton` to false or true.
UISearchBarDelegate
The UISearchBarDelegate protocol defines the optional methods you implement to make a UISearchBar control functional. A UISearchBar object provides the user interface for a search field on a bar, but it’s the application’s responsibility to implement the actions when buttons are tapped. At a minimum, the delegate needs to perform the actual search when text is entered in the text field.
The main function which we will be implementing are
optional func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
We will maintain a boolean variable `searchActive` to decide if the search is in progress.
Steps to implement search
- Create a single view application.
- Select the tableview and set View
- Create IBOutlet from tableview and the searchbar. `CTRL+DRAG` from tableview and searchbar to the viewcontroller.swift
- Lets conform to the UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate. Also in viewDidLoad
set the datasource and delegate to self.
/* Setup delegates */ tableView.delegate = self tableView.dataSource = self searchBar.delegate = self
- Search functionality is very simple. We just filter the `data` array and if it matches the text we create
a new array called `filtered` which holds the text which matches the text in the searchbar.
- Depending on the `searchActive` we return either the `filtered` or the actual `data` in the `numberOfRowsInSection`
and `cellForRowAtIndexPath`
Below is the complete code required to implement the functionality.
import UIKitstruct Candy {let category:Stringlet name:String}class ViewController: UIViewController , UITableViewDelegate , UITableViewDataSource , UISearchBarDelegate , UISearchResultsUpdating{@IBOutlet weak var dataTableView: UITableView!var candies = [Candy]()var filteredCandies = [Candy]()let searchController = UISearchController(searchResultsController: nil)override func viewDidLoad() {super.viewDidLoad()searchController.searchResultsUpdater = selfsearchController.obscuresBackgroundDuringPresentation = truesearchController.searchBar.placeholder = "Search Candies"definesPresentationContext = trueself.navigationController?.navigationItem.searchController = searchControllerself.title = "Candies Name List"searchController.searchBar.scopeButtonTitles = ["All" , "Chocolate" , "Hard" , "Other"]searchController.searchBar.delegate = selfdataTableView.tableHeaderView = searchController.searchBarcandies = [Candy(category: "Chocolate", name: "Chocolate Bar"),Candy(category: "Chocolate", name: "Chocolate Chip"),Candy(category: "Chocolate", name: "Dark Chocolate"),Candy(category: "Hard", name: "Lollipop"),Candy(category: "Hard", name: "Jaw Breaker"),Candy(category: "Hard", name: "Candy Cane"),Candy(category: "Other", name: "Caramel"),Candy(category: "Otehr", name: "Sour Chew"),Candy(category: "Othert", name: "Gummi Bear"),Candy(category: "Other", name: "Candy Floss"),Candy(category: "Chocolate", name: "Chocolate Coin"),Candy(category: "Chocolate", name: "Chocolate Egg"),Candy(category: "Other", name: "Jelly Beans"),Candy(category: "Other", name: "Liquorice"),Candy(category: "Hard", name: "Toffee Apple")]}func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {if isFiltering() {return filteredCandies.count}return candies.count}func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)let candy:Candyif isFiltering() {candy = filteredCandies[indexPath.row]} else {candy = candies[indexPath.row]}cell.textLabel?.text = candy.namecell.detailTextLabel?.text = candy.categoryreturn cell}func filterContentForSearchText(_ searchText:String , scope:String = "All") {filteredCandies = candies.filter({ (candy:Candy) -> Bool inlet doseCategoryMatch = (scope == "All") || (candy.category == scope)if searchBarIsEmpty() {return doseCategoryMatch} else {return doseCategoryMatch && candy.name.lowercased().contains(searchText.lowercased())}})dataTableView.reloadData()}func isFiltering() -> Bool {let searchBarScopeIsFiltering = searchController.searchBar.selectedScopeButtonIndex != 0return searchController.isActive && (!searchBarIsEmpty() || searchBarScopeIsFiltering)}func searchBarIsEmpty() -> Bool {return searchController.searchBar.text?.isEmpty ?? true}func updateSearchResults(for searchController: UISearchController) {let searchBar = searchController.searchBarlet scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]filterContentForSearchText(searchBar.text! , scope: scope)}func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {filterContentForSearchText(searchBar.text! , scope: searchBar.scopeButtonTitles![selectedScope])}}
- AppDelegate code required to implement the functionality.
//// AppDelegate.swift// UISearch//// Copyright © 2018 WeeTech. All rights reserved.//import UIKit@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {var window: UIWindow?func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {let storyBoard:UIStoryboard = UIStoryboard.init(name:"Main" , bundle:nil)let viewController :ViewController = storyBoard.instantiateViewController(withIdentifier: "ViewController") as! ViewControllerlet navigationController = UINavigationController.init(rootViewController: viewController)self.window?.rootViewController = navigationControllerself.window?.makeKeyAndVisible()return true}
- Initial Load
If you want to implement search using parse take.
Please let me know if you have any feedback or questions.
Please let me know if you have any feedback or questions.
Comments
Post a Comment