0

searchBar 텍스트 입력을 기반으로하는 collectionView를 필터링하려고합니다. 나는 UISearchResultsUpdating 클래스의 collectionView를 textDidChange 및 updateSearchResults 함수 호출에서 DB의 모든 사용자와 함께 채울 수 있지만 collectionView는 searchBar 입력을 기반으로 필터링하지 않습니다 (항상 DB의 모든 사용자를 보여줍니다 - 텍스트 입력에서도 표시됨) . 까다로운 부분은 내가 믿는 collectionView (menuBar 클래스) 2 다른 collectionViews 대리자가 있습니다. 각 collectionViews에는 각각 다른 searchBar 및 searchController가 있습니다. 참조 할 수 있도록 첨부 된 스크린 샷과 코드를 참조하십시오. 미리 감사드립니다! 모두 searchControllers와UISearchResults 검색 필터링 모음을 사용하지 않고 searchBar 텍스트를 기반으로 한 뷰

enter image description here enter image description here

// searchVC을

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() 
}