0

我想基于searchBar文本输入过滤collectionView。我能够通过textDidChange和updateSearchResults函数调用,将数据库中的所有用户加载并填充UISearchResultsUpdating类的collectionView,但collectionView不会基于searchBar输入进行过滤(它始终显示数据库中的所有用户 - 即使在文本输入中也是如此) 。我相信棘手的部分是我有一个collectionView(menuBar类),委托给其他2个collectionViews。这些collectionView中的每一个都有一个不同的searchBar和searchController。请参阅附上的截图和代码以供参考。提前致谢!UISearchResultsUpdating不过滤基于searchBar文本的collectionViewBar

enter image description here enter image description here

// searchVC既searchControllers

class SearchVC: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UISearchControllerDelegate, UISearchBarDelegate { 

    var users = [CurrentTraveler]() 
    var isSearching = false 
    var filteredData = [CurrentTraveler]() 

    var peopleResultsViewController: SearchPeopleResultsVC? 

    var filtered:[String] = [] 
    var searchActive : Bool = false 
    var searchPeopleController: UISearchController? 

    let cellId1 = "cellId1" 
    let cellId2 = "cellId2" 

    override func viewDidLoad() { 
     super.viewDidLoad()   
     setupSearchBar() 
     setupCollectionView() 
    } 

    func setupSearchBar() { 
     // sets up searchBar for first collectionView... 
    } 

    func setupCollectionView() { 
     contentCollectionView.dataSource = self 
     contentCollectionView.delegate = self 
     contentCollectionView.register(SearchPeopleCollectionView.self, forCellWithReuseIdentifier: cellId2) 
    } 

    func scrollToMenuIndex(menuIndex: Int) { 
     let indexPath = IndexPath(item: menuIndex, section: 0) 
     contentCollectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition(), animated: true) 

     if indexPath.item == 1 { 
      searchPeopleController?.delegate = self 
      searchPeopleController?.searchBar.delegate = self 

      peopleResultsViewController = SearchPeopleResultsVC() 

      searchPeopleController = UISearchController(searchResultsController: peopleResultsViewController) 
      searchPeopleController?.searchResultsUpdater = peopleResultsViewController 

      navigationItem.titleView = searchPeopleController?.searchBar 
     } 

     if indexPath.item == 0 { 
      // sets up searchController for first collectionView search 
     } 
    } 

//menubar collectionView 
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 2 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId1", for: indexPath) 

     if indexPath.item == 0 { 
      // set up first collectionView in menubar... 
     } 

     if indexPath.item == 1 { 
      let usersCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId2", for: indexPath) as! SearchPeopleCollectionView 
      usersCell.searchVC = self 
      return usersCell 
     } 
     return cell 
    } 

    var filterString = "" { 
     didSet { 
      guard filterString != oldValue else { return } 

      if filterString.isEmpty { 
       filteredData = users 
      } 
      else { 
       filteredData = users.filter { ($0.name?.localizedStandardContains(filterString))! } 
      } 
      peopleResultsViewController?.collectionView.reloadData() 
     } 
    } 

    func updateSearchResults(for searchPeopleController: UISearchController) { 
     filterString = searchPeopleController.searchBar.text ?? "" 

     if filterString.isEmpty { 
      filteredData = users 
     } 
     else { 
      filteredData = users.filter { ($0.name?.localizedStandardContains(filterString))! } 
     } 
     peopleResultsViewController?.collectionView.reloadData() 
    } 

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 
     // should I do anything here...? 
    } 

} 

// UISearchResultsUpdating类

class SearchPeopleResultsVC : UIViewController, UISearchResultsUpdating, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UISearchBarDelegate { 

    let cellId = "cellId" 

    var users = [CurrentTraveler]() 
    var filteredData = [CurrentTraveler]() 
    var isSearching = false 
    var searchVC: SearchVC? 
    var peopleResultsViewController: SearchPeopleResultsVC? 
    var searchController: UISearchController? 
    var searchPeopleCollectionView: SearchPeopleCollectionView? 
    var filtered:[String] = [] 
    var searchActive : Bool = false 

    let searchPeopleController = UISearchController(searchResultsController: nil) 

    lazy var collectionView: UICollectionView = { 
     cv.dataSource = self 
     cv.delegate = self 
     return cv 
    }() 

    override func viewDidLoad() { 
     collectionView.delegate = self 
     collectionView.dataSource = self 

     fetchTravelingUserCell() 
    } 

    func fetchTravelingUserCell() { 
     Database.database().reference().child("users").observe(.childAdded, with: { (snapshot) in 

      if let dictionary = snapshot.value as? [String: AnyObject] { 
       let user = CurrentTraveler(dictionary: dictionary) 
       self.users.append(user) 

       DispatchQueue.main.async(execute: { 
        self.collectionView.reloadData() 
       }) 
      } 
     }, withCancel: nil) 
    } 

    var filterString = "" { 
     didSet { 
      // Return if the filter string hasn't changed. 
      guard filterString != oldValue else { return } 

      if filterString.isEmpty { 
       filteredData = users 
      } 
      else { 
       filteredData = users.filter { ($0.name?.localizedStandardContains(filterString))! } 
      } 
      collectionView.reloadData() 
     } 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     if searchPeopleController.isActive && searchPeopleController.searchBar.text != "" { 
      return filteredData.count 
     } 
     return users.count 
    } 


    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as? BaseGlobalSearchUser else { fatalError("Expected to display a `DataItemCollectionViewCell`.") } 

     if searchPeopleController.isActive && searchPeopleController.searchBar.text != "" { 
      cell.currentTraveler = filteredData[indexPath.item] 
     } else { 
      cell.currentTraveler = users[indexPath.item] 
     } 
     return cell 
    } 

    func updateSearchResults(for searchPeopleController: UISearchController) { 
     filterString = searchPeopleController.searchBar.text ?? "" 
// does print what user types in the searchBar   
print(filterString) 

     if filterString.isEmpty { 
      filteredData = users 
     } 
     else { 
      filteredData = users.filter { ($0.name?.localizedStandardContains(filterString))! } 
     } 
     peopleResultsViewController?.collectionView.reloadData() 
    } 

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 
     if filterString.isEmpty { 
      filteredData = users 
     } 
     else { 
      filteredData = users.filter { ($0.name?.localizedStandardContains(filterString))! } 
     } 
     self.collectionView.reloadData() 
    } 

} 

//数据模型类

class CurrentTraveler: SafeJsonObject { 

    var name: String? 
    var profileImageUrl: String? 
    var travelingPlace: String? 

    init(dictionary: [String: AnyObject]) { 
     super.init() 

     self.name = dictionary["name"] as? String 
     self.profileImageUrl = dictionary["profileImageUrl"] as? String 
     self.travelingPlace = dictionary["users/uid/Places"] as? String 
     setValuesForKeys(dictionary) 
    } 
} 

回答

0

可能是你的filteredString为空。所以你没有获得价值。

所以尝试像下面:

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 
    if filterString.isEmpty { 
     filterString = searchText 
    } 
    if filterString.isEmpty { 
     filteredData = users 
    } else { 
     filteredData = users.filter { ($0.name?.localizedStandardContains(filterString))! } 
    } 
    self.collectionView.reloadData() 
}