26. Juli 2019

Tutorial: UITableView filtern mit UISearchController

Dieses Tutorial zeigt, wie Daten in einem UITableViewController mit der UISearchController-Klasse gefiltert bzw. durchsuchbar gemacht werden können:

Results Filtered

  1. Verwende für dieses Tutorial die aktuelle Version von Xcode (dieses Tutorial wurde zuletzt getestet am 26.7.2019 mit Xcode 10.2).

  2. Verwende das Projekt aus dem UITableViewController-Tutorial oder lade das zugehörige Beispielprojekt Countries. Dieses enthält einen UITableViewController der Daten aus einem Swift-Array zur Anzeige bringt:

    Daten in Tabelle anzeigen

  3. Öffne CountriesTableViewController.swift.

  4. Ergänze die Klasse um eine Methode setupSearch. Deklariere eine Eigenschaft für einen UISearchController - diesem kann ein zweiter ViewController für die Ergebnisanzeige übergeben werden - wird nil als searchResultsController übergeben, erfolgt die Darstellung durch den UIViewController selbst. Implementiere setupSearch so, dass der SearchController beim navigationItem registriert wird (ggf. mit Fallback unter älteren iOS-Versionen):

    class CountriesTableViewController: UITableViewController {
    
        // ...
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.setupSearch()
        }
    
        private var searchController = UISearchController(searchResultsController: nil)
    
        func setupSearch() {
        // UISearchController abhängig von der iOS-Version registrieren
        if #available(iOS 11.0, *) {
            self.navigationItem.searchController = searchController
        } else {
            self.tableView.tableHeaderView = self.searchController.searchBar
        }
    }
    
       // ...
    }
  5. Lass den CountriesTableViewController das UISearchResultsUpdating-Protokoll implementieren und registriere ihn als searchResultsUpdater beim searchController. Implementiere die updateSearchResults-Methode so, dass die Suchergebnisse mit der filter-Methode gefiltert werden und das UITableView aktualisiert wird:

    class CountriesTableViewController: UITableViewController, UISearchResultsUpdating {
    
        var countries = Country.allCountries
        
        // ...
    
        func setupSearch() {
            // ...
            // Aktualisierung der Suchergebnisse via UISearchResultsUpdating-Protokoll
    searchController.searchResultsUpdater = self
        }
        
        func updateSearchResults(for searchController: UISearchController) {
        // Länderliste filtern, wenn ein Suchtext eingegeben wird
        // Ansonsten alle Länder anzeigen - damit wird auch der Cancel-Fall behandelt
        if let searchText = searchController.searchBar.text, !searchText.isEmpty {
            countries = Country.allCountries.filter { (country) in
                country.name.localizedCaseInsensitiveContains(searchText)
            }
        }
        else {
            countries = Country.allCountries
        }
        
        // UITableView aktualisieren
        self.tableView.reloadData()
    }
    
    }
  6. Teste die App, scrolle in der Liste nach oben um das Suchfeld einzublenden und prüfe, dass die Ergebnisse korrekt gefiltert angezeigt werden:

    Results Filtered

  7. Optional kannst Du die Implementierung in setupView noch so anpassen, das die Suchleiste immer sichtbar ist und die Suchergebnisse nicht ausgegraut erscheinen:

    // Such-Bar immer sichtbar machen (nur iOS 11)
    self.navigationItem.hidesSearchBarWhenScrolling = false
    
    // Ausgegraute Darstellung der Suchergebnisse deaktivieren
    searchController.obscuresBackgroundDuringPresentation = false