2016-04-06 8 views
0

Ich versuche, eine Campingplatz-Suchfunktion in meiner App zu erstellen. Ich möchte, dass der Benutzer in der Lage ist, in eine Suchleiste einzutippen und die angezeigte Liste von Campingplätzen so filtern zu lassen, dass sie dem entspricht, was sie tippen. Momentan tippt ein Benutzer auf eine Schaltfläche, um SearchCampgroundsViewController.swift aufzurufen. Hier ist der Code Ich habe bisher in dieser Datei:Der Versuch, UISearchResult in Swift zu verwenden. Wie implementiert man Filter?

import UIKit 

class SearchCampgroundsViewController: UIViewController, UISearchResultsUpdating { 

    let searchController = UISearchController(searchResultsController: nil) 

    @IBOutlet weak var tableView: UITableView! 
    var campgrounds: [Campground]? { 
     return DataProvider.sharedInstance.allCampground() 
    } 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     searchController.searchResultsUpdater = self 
     searchController.hidesNavigationBarDuringPresentation = false 
     searchController.dimsBackgroundDuringPresentation = false 
     self.tableView.tableHeaderView = searchController.searchBar 
    } 


    func updateSearchResultsForSearchController(searchController: UISearchController) { 

    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


} 

extension SearchCampgroundsViewController: UITableViewDataSource { 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return self.campgrounds?.count ?? 0 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("campgroundCell")! as UITableViewCell 
     cell.textLabel?.text = campgrounds?[indexPath.row].facilityName ?? "NO NAME FOR THIS FACILITY" 
     return cell 
    } 
} 

Die Liste von Campingplätzen ist die Anzeige korrekt in der Tabellenansicht (die Liste ist etwa 4000 Artikel lang), und die Suchleiste erscheint, korrekt an der Spitze des Tisches. Ich kann in die Suchleiste tippen, aber die Ergebnisse filtern nicht. Wie implementiere ich Filter? Was muss in die Funktion updateSearchResultsForSearchController gehen?

Antwort

0

Sie müssen Ihre Datenquelle (campgrounds) mithilfe des in die Suchleiste eingegebenen Texts filtern (searchController.searchBar.text) und dann Ihre Tabellenansicht mit den gefilterten Daten neu laden.

Wenn Sie Ihre Datenquelle als berechnete Eigenschaft beibehalten möchten, müssen Sie eine neue Variable definieren, die ein Array der gefilterten Campingplätze enthält (siehe unten). Sie müssen dann Prüfungen einführen, um zu bestimmen, welche Datenquelle verwendet werden soll, abhängig davon, ob der Such-Controller aktiv ist oder nicht.

Alternativ können Sie eine einzelne Datenquelle verwenden, die bei Bedarf ein Array von gefilterten oder ungefilterten Campgrounds zurückgibt.

Beachten Sie, dass Sie import Foundation verwenden müssen, um rangeOfString() zu verwenden.

versuchen, etwas entlang der folgenden Zeilen:

import Foundation 

/* ... */ 

var filtered: [Campground]? 

func updateSearchResultsForSearchController(searchController: UISearchController) {   
    filtered = campgrounds?.filter { 
     // True if facilityName contains search bar text (case-sensitive). 
     $0.facilityName.rangeOfString(searchController.searchBar.text!) != nil 
    } 

    tableView.reloadData() 
} 

/* ... */ 

extension SearchCampgroundsViewController: UITableViewDataSource 
{ 
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     if searchController.active && !searchController.searchBar.text.isEmpty { 
      return filtered?.count ?? 0 
     } 

     return campgrounds?.count ?? 0 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("campgroundCell")! as UITableViewCell 

     if searchController.active && searchController.searchBar.text != "" { 
      cell.textLabel?.text = filtered?[indexPath.row].facilityName ?? "NO NAME FOR THIS FACILITY" 
     } else { 
      cell.textLabel?.text = campgrounds?[indexPath.row].facilityName ?? "NO NAME FOR THIS FACILITY" 
     } 

     return cell 
    } 
} 
+0

Vielen Dank für Ihre Antwort. Ich habe diesen Code implementiert. Es filtert, wenn auch nicht sehr genau. Wenn ich beispielsweise ein "D" eintippe, werden immer noch die Elemente am Anfang der Liste angezeigt, die mit A beginnen. Wenn ich auf die Suchleiste klicke, wird die Liste ebenfalls ausgeblendet. Welcher Teil des Codes kontrolliert dies? – Impulso

+0

Re Genauigkeit - das Filterkriterium, das im Beispielcode verwendet wird, ist, ob der facilityName den Suchtext enthält, nicht ob der facilitiesName mit dem Suchtext beginnt. Wenn Sie das letztere bevorzugen, können Sie 'rangeOfString()' durch 'hasPrefix()' ersetzen. – jamesk

+0

Re-Verschwinden-Liste - Dies wird wahrscheinlich von den Teilen des Beispiel-Codes kontrolliert, die 'self.searchController.active' prüfen (was wahr ist, sobald Sie auf die Suchleiste tippen). Ich habe diese Teile bearbeitet, um eine Überprüfung hinzuzufügen, um sicherzustellen, dass der Text der Suchleiste nicht leer ist. Das sollte verhindern, dass die ursprüngliche Liste von Campingplätzen verschwindet, bis ein Text in die Suchleiste eingegeben wurde. – jamesk