I’ve implement search performance on desk view and it working high quality and in a position to filter the information. whereas knowledge is filtering , the desk view cell is replace and reloaded appropriately. After I completed typing knowledge into search bar and choose the filtered cell , I’m anticipating to point out chosen filtered cell knowledge into particulars view controller when the didSelectRowAt perform known as. But it surely not exhibiting the information from filtered cell , it exhibiting completely different cell knowledge.
Right here is my view mannequin code the place I’ve search perform.
// MARK: - Search perform.
enum MoviesViewModelState {
case loading
case loaded([Movie])
case error
var films: [Movie] {
swap self {
case .loaded(let films):
return films
case .loading, .error:
return []
}
}
}
/// Calling API for film knowledge. right here
ultimate class MoviesViewModel {
/// API name is occurring right here.
}
extension MoviesViewModel {
public func inSearchMode(_ searchController: UISearchController) -> Bool {
let isActive = searchController.isActive
let searchText = searchController.searchBar.textual content ?? ""
return isActive && !searchText.isEmpty
}
public func updateSearchController(searchBarText: String?) {
self.filteredMovie = state.films
if let searchText = searchBarText?.lowercased() {
guard !searchText.isEmpty else { return }
self.filteredMovie = self.filteredMovie.filter({ $0.title.lowercased().incorporates(searchText) })
}
}
}
Right here is the desk view controller code ..
ultimate class MoviesViewController: UITableViewController {
personal let viewModel: MoviesViewModel
// MARK: - UI Elements
personal let searchController = UISearchController(searchResultsController: nil)
init(viewModel: MoviesViewModel) {
self.viewModel = viewModel
tremendous.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been carried out")
}
override func viewDidLoad() {
tremendous.viewDidLoad()
title = LocalizedString(key: "films.title")
setupSearchController()
configureTableView()
updateFromViewModel()
bindViewModel()
viewModel.fetchData()
}
personal func configureTableView() {
tableView.dm_registerClassWithDefaultIdentifier(cellClass: MovieCell.self)
tableView.rowHeight = UITableView.automaticDimension
refreshControl = UIRefreshControl()
refreshControl?.addTarget(self, motion: #selector(refreshData), for: .valueChanged)
}
personal func bindViewModel() {
viewModel.updatedState = { [weak self] in
guard let self else { return }
DispatchQueue.fundamental.async {
self.updateFromViewModel()
}
}
}
personal func updateFromViewModel() {
swap viewModel.state {
case .loading, .loaded:
tableView.reloadData()
case .error:
showError()
}
refreshControl?.endRefreshing()
}
// MARK: setUpSearch Property.
personal func setupSearchController() {
self.searchController.searchResultsUpdater = self
self.searchController.obscuresBackgroundDuringPresentation = false
self.searchController.hidesNavigationBarDuringPresentation = false
self.searchController.searchBar.placeholder = "Search Film"
self.navigationItem.searchController = searchController
self.definesPresentationContext = false
self.navigationItem.hidesSearchBarWhenScrolling = false
searchController.delegate = self
searchController.searchBar.delegate = self
searchController.searchBar.showsBookmarkButton = true
searchController.searchBar.tintColor = .purple
searchController.searchBar.setImage(UIImage(named: "Filter"), for: .bookmark, state: .regular)
searchController.searchBar.setLeftImage(UIImage(named: "Search"))
searchController.searchBar.showsBookmarkButton = true
}
@objc personal func refreshData() {
viewModel.fetchData()
}
@objc personal func textSizeChanged() {
tableView.reloadData()
}
}
// MARK: - UITableViewDataSource
extension MoviesViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection part: Int) -> Int {
let inSearchMode = self.viewModel.inSearchMode(searchController)
return inSearchMode ? self.viewModel.filteredMovie.depend : self.viewModel.state.films.depend
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: MovieCell = tableView.dm_dequeueReusableCellWithDefaultIdentifier()
let inSearchMode = self.viewModel.inSearchMode(searchController)
let film = inSearchMode ? self.viewModel.filteredMovie[indexPath.row] : self.viewModel.state.films[indexPath.row]
cell.configure(film)
return cell
}
}
// MARK: - UITableViewControllerDelegate
extension MoviesViewController {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let film = viewModel.state.films[indexPath.row]
let viewModel = MoviesDetailsViewModel(film: film, apiManager: APIManager())
let viewController = MovieDetailsViewController(viewModel: viewModel)
self.navigationController?.pushViewController(viewController, animated: true)
}
}
// MARK: - Search Controller Features
extension MoviesViewController: UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate {
func updateSearchResults(for searchController: UISearchController) {
self.viewModel.updateSearchController(searchBarText: searchController.searchBar.textual content)
tableView.reloadData()
}
}
Right here is the screenshot of the filtering knowledge.. after I choose the primary filtered cell (the Godfather) , I’m anticipating to point out the main points of that cell into particulars view controller.
[
But here is the result when I select the filtered cell and it showing the wrong data into details view controller.