Erik Batista
Erik Batista

Reputation: 227

searchBar has trouble filtering swift 3

Okay, I hope this is going to make sense:

So what I'm trying to do is filter usernames into the collectionView that I get from firebase. I have it all set up, it fetches the usernames and displays it onto the collection view when I click the search bar. When I start typing on the search bar, it does filter usernames BUT not on the UI.

The reason for this is because the search bar and the collectionViews it shows when clicked to filter usernames, are in different classes.

Still don't know what I'm trying to say? Here's what I mean:

click here for the searchBar & CollectionViewController together picture

click here to for the searchBar & collection View

UserSearchController with the relevant code:

var users = [User]()
func fetchUsers() {
    let ref = FIRDatabase.database().reference().child("users")
    ref.observe(.value, with: { (snapshot) in
        guard let dictionaries = snapshot.value as? [String: Any] else { return }

        //For each iterates through every object in the dictioary
        dictionaries.forEach({ (key, value) in

            guard let userDictionary = value as? [String: Any] else { return}
            let user = User(uid: key, dictionary: userDictionary)
            self.users.append(user)
            print(user.uid, user.username)
        })
        self.collectionView?.reloadData()

    }) { (error) in
        print("failed to fetch users:", error)
    }
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    self.users = self.users.filter { (user) -> Bool in
        print(",here:",user)
        return user.username.contains(searchText)
    }
    self.collectionView?.reloadData()
}

UserSearchCV with relevant code:

var users = [User]()
func fetchUsers() {

    let ref = FIRDatabase.database().reference().child("users")
    ref.observe(.value, with: { (snapshot) in
        guard let dictionaries = snapshot.value as? [String: Any] else { return }

        //For each iterates through every object in the dictioary
        dictionaries.forEach({ (key, value) in

            guard let userDictionary = value as? [String: Any] else { return}
            let user = User(uid: key, dictionary: userDictionary)
            self.users.append(user)
            print(user.uid, user.username)
        })
        self.collectionView?.reloadData()

    }) { (error) in
        print("failed to fetch users:", error)
    }
}


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

//let numberOfUsers = UserSearchController.searchBar(users.count) did you mean to use a value of this type instead?
    return users.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! UserSearchCVCell
    //        let filteredUsers = UserSearchController.searchBar(users.count)
    //        cell.user = filteredUsers[indexPath.item]
    cell.user = users[indexPath.item]
    return cell
}

The code that has been commented out would be nice but it doesn't let me it compiles an error with 'Instance member 'searchBar cannot be used on type 'UserSearchController'.

var users = User sample data:

struct User {
let uid: String
let username: String
let profileImageUrl: String
let videos: String
init(uid: String, dictionary: [String: Any]) {
    self.uid = uid
    self.username = dictionary["username"] as? String ?? ""
    self.profileImageUrl = dictionary["profileImageUrl"] as? String ?? ""
    self.videos = dictionary["Videos"] as? String ?? ""
}

}

Let me know if you have any questions with understanding the problem. Thank you!

Upvotes: 0

Views: 99

Answers (1)

3stud1ant3
3stud1ant3

Reputation: 3606

After discussion with OP, we have found a solution

please follow these

first update your searchBar method as follows

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 


self.users = self.users.filter { (user) -> Bool in 
print(",here:",user) 
delegate?.passFilterArray(self.users) 
return user.username.contains(searchText) 

} 
searchUsersCV.isHidden = true 
searchUsersCV.updateUsersView(self.users) 

self.collectionView?.reloadData() 
}

and then in UserSearchCV add this

func updateUsersView(_ users: [User]) { 

self.users = users 
print(self.users) 
self.collectionView.reloadData() 
}

Upvotes: 1

Related Questions