Home > Back-end >  SearchBar doesn't returns results until activated and typing
SearchBar doesn't returns results until activated and typing

Time:09-25

I see empty rows when my tableView is loaded for the first time. But if I activate searchBar, write something into textField everything works correctly even i clean all the text. I want the app works without these extra steps. But I don't understand where exactly I am making the mistake.

class NextTableViewCell: UITableViewController, UISearchBarDelegate, UISearchControllerDelegate {

@IBOutlet weak var searchBar: UISearchBar!

    var ref: DatabaseReference?
    let db = Firestore.firestore()
    var messages: [Message] = []
    var filteredMessages: [Message] = []

    override func viewDidLoad() {
    super.viewDidLoad()
    searchBar.delegate = self
    tableView.dataSource = self    
    loadMessages()       
    filteredMessages = messages
}

Func loadMessages retrieves data from Firebase

   func loadMessages() {
    let user =  Auth.auth().currentUser?.email
    let docRef = db.collection(K.FStore.collectionName).document(user!)
    docRef.addSnapshotListener { (querySnapshot, error) in
        self.messages = []
        if let e = error {
            print(e)
        } else {
            if let snapshotDocuments = querySnapshot?.data(){
                for item in snapshotDocuments {
                    if let key = item.key as? String, let translate = item.value as? String {
                        let newMessage = Message(key: key, value: translate)
                        self.messages.append(newMessage)
                    }
                }
                DispatchQueue.main.async { [self] in
                        self.messages.sort(by:  {$1.key > $0.key})
                        self.tableView.reloadData()
                    }
                }
            }
        }
    }

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return filteredMessages.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let message = filteredMessages[indexPath.row]
    let cell = tableView.dequeueReusableCell(withIdentifier: "ListVC", for: indexPath)
    cell.textLabel?.text = message.key   " - "   message.value

    
    return cell
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    
    filteredMessages = []
        
    if searchText == "" {
        
        filteredMessages = messages
        
    }else{
    
        for item in messages {
            if item.key.lowercased().contains(searchText.lowercased()){
                if let key = item.key as? String, let translate = item.value as? String {

                    let newMessage = Message(key: key, value: translate)
                    self.filteredMessages.append(newMessage)
                }
            }
         
        }
    }
    
    tableView.reloadData()

}

CodePudding user response:

The problem is that filteredMessages is empty when the view controller loads and only gets populated when you search.

Since filteredMessages is essentially a subset of messages, you need to set filteredMessages to messages upon fetching them from the database.

Try adding a line that does that in your loadMessages() method:

DispatchQueue.main.async { [self] in
    self.messages.sort(by:  {$1.key > $0.key})
    self.filteredMessages = self.messages // Add this line
    self.tableView.reloadData()
}
  • Related