0

I am trying to filter a collectionView based on searchBar text inputs. I am able to load and populate the UISearchResultsUpdating class's collectionView with all the users in the DB on textDidChange and updateSearchResults function call, but the collectionView does not filter based on searchBar inputs (it always shows all users in the DB - even on text inputs). The tricky part I believe is I have a collectionView(menuBar class) that delegates to 2 other collectionViews. Each 1 of those collectionViews has a different searchBar and searchController. See attached screenshots and code for reference. Thanks in advance!

enter image description here enter image description here

// searchVC with both 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

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

}

// data model class

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)
    }
}
user3708224
  • 1,229
  • 4
  • 19
  • 37

1 Answers1

0

May be your filteredString is empty. So you are not getting values.

So try like the below :

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()
}
Vini App
  • 7,339
  • 2
  • 26
  • 43