Reputation: 227
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
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