2016-11-10 7 views
2

Ich habe eine UITableViewCell mit 3 Subviews, Ich mag würde filtern, wenn ich suche, wie hier zu sehen:UISearchController Filter Swift

TableViewCell Example

1.Die Bildansicht 2.Die Namensschild (schwarzer Text) 3.Die Straßennamensschild (blauer Text)

das ist, was ich bisher gemacht habe, habe es geschafft, ich nur zu verstehen, wie 1-Array zu filtern, die der Name ist:

MainTableView.swift

var FilteredNames = [String] 

    func updateSearchResultsForSearchController(searchController:UISearchController) { 

      // Filter Names 
      self.filteredNames = self.names.filter { (name:String) -> Bool in 
       if name.lowercaseString.containsString(self.searchController.searchBar.text!.lowercaseString){ 
        return true 
       } else { 
        return false 
       } 
      } 
      self.resultsController.tableView.reloadData() 
     } 
     override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
      return 100.5 
     } 

     override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

      // Search 
      if tableView == self.tableView { 
       self.streets.count 
       return self.names.count 
      } else { 
       self.filteredStreets.count 
      return self.filteredNames.count 
      }    
      // return names.count 
      } 

     override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ 

      let cell = self.tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell 

      if tableView == self.tableView { 
       cell.photo.image = self.images[indexPath.row] 
       cell.name.text = names[indexPath.row] 
       cell.streetName.text = streets[indexPath.row] 
      } else { 
       cell.photo.image = self.images[indexPath.row] 
       cell.name.text = self.filteredNames[indexPath.row] 
       cell.streetName.text = self.streets[indexPath.row] 
      } 
      return cell 
     } 

Ab jetzt, wenn ich suche, die Bildansicht & die Straße Etikett mit dem Namen nicht synchronisiert ist. Ich möchte alle 3 Untersichten filtern, um korrekt zu synchronisieren. Wie kann ich das erreichen?

Ich verstehe, ich muss eine Struktur verwenden und alle 3 mit einem Objekt filtern, aber ich bin auf einige Schwierigkeiten gestoßen, das zu tun, dass jede Hilfe geschätzt wird, danke!

Edit: hier ist mein Code jetzt:

override func viewDidLoad() { 
      super.viewDidLoad() 

    var searchController : UISearchController! 

    var resultsController = UITableViewController() 

    // // 
     definesPresentationContext = true 
     self.resultsController.tableView.dataSource = self 
     self.resultsController.tableView.delegate = self 
     self.searchController = UISearchController(searchResultsController: self.resultsController) 
     self.tableView.tableHeaderView = self.searchController.searchBar 
     self.searchController.searchResultsUpdater = self 
     self.searchController.dimsBackgroundDuringPresentation = true 
     self.searchController.searchBar.sizeToFit() 
     self.searchController.searchBar.barTintColor = UIColor.blackColor() 
     self.searchController.searchBar.endEditing(true) 
     self.searchController.searchBar.placeholder = "חפש ברים" 



     allUsers = createUsers(names: names, streets: streets, images: images) 

      filteredUsers = allUsers 

      } 

     var allUsers: [User]! 
     var filteredUsers: [User]! 

     func createUsers(names names: [String], streets: [String], images: [UIImage?]) -> [User] { 
      var users = [User]() 
      guard names.count == streets.count && names.count == images.count else { return users } 
      for (index, name) in names.enumerate() { 
       let user = User(name: name, streetName: streets[index], image: images[index]) 
       users.append(user) 
      } 
      return users 
     } 




     //MARK : Search ! 
     func updateSearchResultsForSearchController(searchController:UISearchController) { 
      if let searchText = searchController.searchBar.text?.lowercaseString { 
       if searchText.characters.count == 0 { 
        filteredUsers = allUsers 
       } 
       else { 
        filteredUsers = allUsers.filter { 
         return $0.name.lowercaseString.containsString(searchText) || 
          $0.streetName.lowercaseString.containsString(searchText) 
        } 
       } 
      } 
      self.resultsController.tableView.reloadData() 
     } 

     override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 
     { 
      return 100.5; 
     } 

     override func didReceiveMemoryWarning() { 
      super.didReceiveMemoryWarning() 
      //////// 

        //////// 
     } 

     override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
      return filteredUsers.count 
     } 

     override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ 
      let cell = self.tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell 
      let user = filteredUsers[indexPath.row] 
      cell.photo.image = user.image 
      cell.name.text = user.name 
      cell.streetName.text = user.streetName 
      return cell 
     } 
+0

ab [Moment] (https://www.youtube.com/watch?v=SgEO7nni5CQ&feature= youtu.be & t = 2318) sehen Sie ein paar Minuten des Stanford - Kurses. ** H ** e benutzt 'didSet' +' reloadData'. Ich denke, es ist hilfreich für die Lösung Ihres Problems – Honey

Antwort

4

ich stark nur eine dataSource statt separate Arrays für Namen, Straßennamen und die Bilder haben würde empfehlen. Im folgenden Code wird filteredUsers immer als dataSource verwendet und allUsers ist nur ein gespeichertes vollständiges Array, das für die Aktualisierung filteredUsers jedes Mal verwendet wird, wenn ein neuer Text in Suchleiste eingegeben wird.

Erstellen Sie ein Modell:

struct User { 
    var name: String 
    var streetName: String 
    var image: UIImage? 
} 

Viewcontroller:

var allUsers: [User]! 
var filteredUsers: [User]! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    //assuming you already have three arrays with the same amount of elements in each: 
    allUsers = createUsers(names: names, streets: streets, images: images) 

    filteredUsers = allUsers 
} 

func createUsers(names names: [String], streets: [String], images: [UIImage?]) -> [User] { 
    var users = [User]() 
    guard names.count == streets.count && names.count == images.count else { return users } 
    for (index, name) in names.enumerate() { 
     let user = User(name: name, streetName: streets[index], image: images[index]) 
     users.append(user) 
    } 
    return users 
} 

func updateSearchResultsForSearchController(searchController:UISearchController) { 
    if let searchText = searchController.searchBar.text?.lowercaseString { 
     if searchText.characters.count == 0 { 
      filteredUsers = allUsers 
     } 
     else { 
      filteredUsers = allUsers.filter { 
       return $0.name.lowercaseString.containsString(searchText) || 
         $0.streetName.lowercaseString.containsString(searchText) 
      } ?? [] 
     }    
    } 
    self.resultsController.tableView.reloadData() 
} 


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

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ 
    let cell = self.tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell 
    let user = filteredUsers[indexPath.row] 
    cell.photo.image = user.image 
    cell.name.text = user.name 
    cell.streetName.text = user.streetName 
    return cell 
} 
+0

Ist dies ein Beispiel für Ihren Code oder eine Lösung für meine Situation? –

+0

Wenn ich Sie richtig verstanden habe, ist es die Lösung für Ihre Situation. Das Element wird gefiltert, wenn 'streetName' oder' name' die eingegebene Suchzeichenfolge enthält. Wenn Sie ein einzelnes Modell verwenden, werden Sie die desynchronisierten Etiketten löschen, die Sie jetzt haben. – alexburtnik

+0

'Wert des Typs 'BarsViewController.User' hat kein Mitglied 'image'' Ich erhalte diesen Fehler –

Verwandte Themen