The search bar in my app isn't working. Ive narrowed down the problem to the method cellforRowAt. It's not able to show the search result when word are typed. Can someone please assist me ? Project Link: https://github.com/lexypaul13/Covid-News.git
Code Block func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { //determines what data source should be used when user types if isFiltering{ return filteredArticles?.count ?? 0 } return articles?.count ?? 0 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! NewsTableViewCell let news: Articles filteredArticles = articles if isFiltering{ news = filteredArticles![indexPath.row] } else{ news = articles![indexPath.row] } cell.authorName.text = filteredArticles?[indexPath.row].author cell.headLine.text = filteredArticles?[indexPath.row].title cell.newsImage.downloadImage(from:(self.filteredArticles?[indexPath.item].urlImage ?? "nill")) cell.timePublication.text = filteredArticles?[indexPath.row].publishedAt if let dateString = filteredArticles?[indexPath.row].publishedAt, let date = indDateFormatter.date(from: dateString){ let formattedString = outDateFormtter.string(from: date) cell.timePublication.text = formattedString } else { cell.timePublication.text = "----------" } return cell } func updateSearchResults(for searchController: UISearchController) { let searchBar = searchController.searchBar filterContentForSearchText(searchBar.text!, articles!) } func filterContentForSearchText(_ searchText:String ,_ category: [Articles]){ filteredArticles = articles?.filter({ (article:Articles) -> Bool in return article.description.lowercased().contains(searchText.lowercased()) }) table_view.reloadData() }
A first practical advice. When you paste code here, use "Paste and match style" to avoid all the extra blank lines that make code hard to read:
Now, back to your code.
In comment line 1, you say:
But effectively, isFiltering is doing so.
I don't understand the logic.
Line 11 (my numbering), you set filteredArticles to articles.
What is the insterest then of this filteredArticles ?
Shouldn't the function be like :
Question: why do you make articles an optional ?
Note: use of underscore as in table_view in discouraged in Swift.
You'd better give a meaningful name with CamelCase writing, for instance:
articlesTableView
Code Block func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // determines what data source should be used when user types if isFiltering { return filteredArticles?.count ?? 0 } return articles?.count ?? 0 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! NewsTableViewCell let news: Articles filteredArticles = articles if isFiltering { news = filteredArticles![indexPath.row] } else { news = articles![indexPath.row] } cell.authorName.text = filteredArticles?[indexPath.row].author cell.headLine.text = filteredArticles?[indexPath.row].title cell.newsImage.downloadImage(from:(self.filteredArticles?[indexPath.item].urlImage ?? "nill")) cell.timePublication.text = filteredArticles?[indexPath.row].publishedAt if let dateString = filteredArticles?[indexPath.row].publishedAt, let date = indDateFormatter.date(from: dateString){ let formattedString = outDateFormtter.string(from: date) cell.timePublication.text = formattedString } else { cell.timePublication.text = "----------" } return cell } func updateSearchResults(for searchController: UISearchController) { let searchBar = searchController.searchBar filterContentForSearchText(searchBar.text!, articles!) } func filterContentForSearchText(_ searchText:String ,_ category: [Articles]){ filteredArticles = articles?.filter({ (article:Articles) -> Bool in return article.description.lowercased().contains(searchText.lowercased()) }) table_view.reloadData() }
Now, back to your code.
In comment line 1, you say:
That's not the case, I hope you don't count on this for the selection.func tableView(_ tableView: UITableView, numberOfRowsInSection…) determines what data source should be used when user types
But effectively, isFiltering is doing so.
I don't understand the logic.
Line 11 (my numbering), you set filteredArticles to articles.
What is the insterest then of this filteredArticles ?
Shouldn't the function be like :
Code Block func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! NewsTableViewCell let news: Articles var articlesToUse = articles // by default // Get rid of this filteredArticles = articles if isFiltering { articlesToUse = filteredArticles // news = filteredArticles![indexPath.row] } /* Remove else { news = articles![indexPath.row] } */ news = articlesToUse![indexPath.row] cell.authorName.text = articlesToUse?[indexPath.row].author // instead of filteredArticles // The same on following lines
Question: why do you make articles an optional ?
Note: use of underscore as in table_view in discouraged in Swift.
You'd better give a meaningful name with CamelCase writing, for instance:
articlesTableView