2017-04-23 3 views
2

Ich habe eine Reihe von Studios. Jedes Studio hat eine Eigenschaft namens studioName.Filter Array von Objekten auf Eigenschaft mit NSPredicate

Ich brauche mein Suchfeld, um die Studios basierend auf dem studioName zu filtern, die vom Benutzer auf das Suchfeld angewendet wurden.

Hier ist mein aktueller Code:

var studios = [Studio]() 
var filteredStudios = [Studio]() 
var studiosToDisplay = [Studio]() 

func updateSearchResultsForSearchController(searchController: UISearchController) { 
    let searchText = searchController.searchBar.text 

    print("SEARCH TEXT: \(searchText)") 

    if searchText == nil || searchText!.isEmpty { 
     studiosToDisplay = studios 
     self.resultTableView.reloadData() 
     NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) //Calls SearchVC 
    } else { 
     studiosToDisplay.removeAll() 
     let searchPredicate = NSPredicate(format: "studioName CONTAINS[c] %@", searchText!) 
     let array = (self.studios as NSArray).filteredArrayUsingPredicate(searchPredicate) 
     studiosToDisplay = array as! [Studio] 
     self.resultTableView.reloadData() 
    } 
} 

Es ist einfach nicht Weicht arbeiten, gerade jetzt .. Es filtert, aber ich am Ende mit dem gleichen Studio jedes Mal verlassen, egal, was ich im Suchfeld setzen.

Ich denke, ich muss das Prädikat wissen, dass es jedes Mal auf das einzelne Objekt im Array schauen muss. Aber ich kann einfach nicht herausfinden, wie. Ich habe versucht, "ANY" in dem Format hinzuzufügen, aber das stürzt meine App ab.

+0

Sie sollten Ihre Frage richtig markieren, da Sie Swift 2 zu verwenden scheinen (ich empfehle Ihnen, Ihren Xcode auf den neuesten im App Store erhältlichen Xcode zu aktualisieren) –

+0

Eine Randnotiz: Mit 'searchText == nil' nach nil suchen , dann force unwrapping ('searchText!') ist wirklich eine schlechte Übung – Alexander

Antwort

7

Dies ist unnötig komplex. Es gibt keine Notwendigkeit für NSPredicate hier.

var studios = [Studio]() 
var filteredStudios = [Studio]() 
var studiosToDisplay = [Studio]() 

func updateSearchResultsForSearchController(searchController: UISearchController) { 
    let searchText = searchController.searchBar.text 

    print("SEARCH TEXT: \(searchText)") 

    if let searchText = searchText, !searchText.isEmpty { 
     studiosToDisplay = studios.filter{ $0.studioName.contains(searchText) } 
    } 
    else { 
     studiosToDisplay = studios 
     NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) //Calls SearchVC 
    } 

    self.resultTableView.reloadData() 
} 
1

Dank .. @Alexander Hier ist der Code, den ich am Ende mit:

func updateSearchResultsForSearchController(searchController: UISearchController) { 

    let searchText = searchController.searchBar.text 

    if let searchText = searchText { 
     if !searchText.isEmpty { 
      self.studiosToDisplay = self.studios.filter { $0.studioName!.containsString(searchText) } 
      for studio in self.studiosToDisplay { 
       print("\(studio.studioName!)") 
      } 
     } 
     else { 
      self.studiosToDisplay = self.studios 
      NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) // Calls SearchVC 
     } 
    } 

    self.resultTableView.reloadData() 

} 

ich herausgefunden, dass mein ehemaliger Code, mit dem NSPredicate war eigentlich funktional - ich die falsche gerade präsentiert wurde Array in meinem Tableview .. Ups .. Aber jetzt funktioniert es, und ich halte mich an den einfacheren Code. Ich weiß nicht, warum ich nicht daran gedacht habe, die $ 0-Funktion zu benutzen :) Wie auch immer, danke!

+0

Sie können eine Guard-Anweisung verwenden, um 'searchText' ohne diese zusätzliche Einrückungsebene zu binden – Alexander

Verwandte Themen