uitableviewuisearchbaruisearchbardelegateindexpath

Swift SearchBar inTableView doesn't show the correct Data in the filtered rows


My app is using Firebase Realtime Database to store information of each user. The tableView works fine. I added a searchBar and when I type letters in the searchBar, I can see that the amount of rows presented in the tableView is equal to the amount of users which contain these letters in their names. The problem is that the rows presented in the tableview (after typing letters in the search bar), contain the information of the first user till x user (x = amount of users which contain these letters in their names).

import UIKit
import FirebaseDatabase
import Firebase

class VideoListScreen: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    var blogPost: [BlogPost] = []
    var searchBlogPost = [BlogPost]()
    var searching = false

    override func viewDidLoad() {
        super.viewDidLoad()

        blogPost = []
        createArray()
        tableView.delegate = self
        tableView.dataSource = self

    }

    func createArray() {
        let ref = Database.database().reference().child("Users")

        ref.observe(.childAdded, with: { (snapshot) in
            if let postDict = snapshot.value as? [String : String] {
                let post = BlogPost(name:postDict["name"] ?? "" , gaf: postDict["gaf"] ?? "", place: postDict["place"] ?? "", phone: postDict["phone"] ?? "", notes: postDict["notes"] ?? "", elsertext: postDict["elsertext"] ?? "")

                self.blogPost.append(post)
                self.tableView.reloadData()
            }
        })
    }
}

extension VideoListScreen: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if searching{
            return searchBlogPost.count
        }else{
           return blogPost.count
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let blogp = blogPost[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "Tavla") as! Tavla
        if searching{
            cell.setBLogPost(blogPost: searchBlogPost[indexPath.row])
        }
        else{
            cell.setBLogPost(blogPost: blogPost[indexPath.row])
        }
        cell.setBLogPost(blogPost: blogp)
        return cell
    }
}

extension VideoListScreen: UISearchBarDelegate {
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        searchBlogPost = blogPost.filter({$0.name.prefix(searchText.count) == searchText})
        searching = true
        tableView.reloadData()
    }
}

I Believe the problem is in the if and else statments in this function:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let blogp = blogPost[indexPath.row]
    let cell = tableView.dequeueReusableCell(withIdentifier: "Tavla") as! Tavla
    if searching{
        cell.setBLogPost(blogPost: searchBlogPost[indexPath.row])
    }
    else{
        cell.setBLogPost(blogPost: blogPost[indexPath.row])
    }
    cell.setBLogPost(blogPost: blogp)
    return cell
}

enter image description here

enter image description here


Solution

  • You have extra cell.setBLogPost(blogPost: blogp) in your delegate methode

      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          let blogp = blogPost[indexPath.row]
          let cell = tableView.dequeueReusableCell(withIdentifier: "Tavla") as! Tavla
          if searching{
              cell.setBLogPost(blogPost: searchBlogPost[indexPath.row])
          }
          else{
              cell.setBLogPost(blogPost: blogPost[indexPath.row])
          }
    
          return cell
      }
    

    I think this will solve your problem and you can use

        import UIKit
    import FirebaseDatabase
    import Firebase
    
    class VideoListScreen: UIViewController {
    
        @IBOutlet weak var tableView: UITableView!
        var blogPost: [BlogPost] = []
        var searchBlogPost = [BlogPost]()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            blogPost = []
            createArray()
            tableView.delegate = self
            tableView.dataSource = self
    
        }
    
        func createArray() {
            let ref = Database.database().reference().child("Users")
    
            ref.observe(.childAdded, with: { (snapshot) in
                if let postDict = snapshot.value as? [String : String] {
                    let post = BlogPost(name:postDict["name"] ?? "" , gaf: postDict["gaf"] ?? "", place: postDict["place"] ?? "", phone: postDict["phone"] ?? "", notes: postDict["notes"] ?? "", elsertext: postDict["elsertext"] ?? "")
    
                    self.blogPost.append(post)
    
                    self.searchBlogPost = self.blogPost
                    self.tableView.reloadData()
                }
            })
        }
    }
    
    extension VideoListScreen: UITableViewDataSource, UITableViewDelegate {
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
          return searchBlogPost.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let blogp = searchBlogPost[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: "Tavla") as! Tavla
            cell.setBLogPost(blogPost: blogp)
            return cell
        }
    }
    
    extension VideoListScreen: UISearchBarDelegate {
        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    
            if ((searchText.trimmingCharacters(in: .whitespaces).isEmpty) {
              searchBlogPost = blogPost
            } else {
              searchBlogPost = blogPost.filter({$0.name.prefix(searchText.count) == searchText})
            }
    
            tableView.reloadData()
        }
    }
    

    I hope this will helps.