HomeiOS Developmentios - Search performance shouldn't be working in desk view

ios – Search performance shouldn’t be working in desk view


I’ve created a search bar programmatically and I additionally outlined the search operate as effectively. However the issue is after I enter the textual content into the search bar, it isn’t filtering the info. I’ve set the filtered knowledge into the viewDidLoad technique.

Right here is the view mannequin code.

enum MoviesViewModelState {
    case loading
    case loaded([Movie])
    case error

    var motion pictures: [Movie] {
        swap self {
        case .loaded(let motion pictures):
            return motion pictures
        case .loading, .error:
            return []
        }
    }
}

closing class MoviesViewModel {
    
    non-public let apiManager: APIManaging
    
    init(apiManager: APIManaging = APIManager()) {
        self.apiManager = apiManager
    }
    
    var updatedState: (() -> Void)?
    
    var state: MoviesViewModelState = .loading {
        didSet {
            updatedState?()
        }
    }
    
    func fetchData() {
        apiManager.execute(Film.topRated) { [weak self] lead to
            swap end result {
            case .success(let web page):
                self?.state = .loaded(web page.outcomes)
            case .failure:
                self?.state = .error
            }
        }
    }
}

Right here is the view controller code.

import UIKit

closing class MoviesViewController: UITableViewController, UISearchResultsUpdating {
    
    non-public let viewModel: MoviesViewModel
    non-public var filteredData: [Movie] = []
    var searchViewController: UISearchController!
    
    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: "motion pictures.title")

        NotificationCenter.default.addObserver(self, selector: #selector(textSizeChanged), identify: UIContentSizeCategory.didChangeNotification, object: nil)
        filteredData = viewModel.state.motion pictures
        searchViewController = UISearchController(searchResultsController: nil)
        searchViewController.searchResultsUpdater = self
        
        configureSearchBar()
        configureTableView()
        updateFromViewModel()
        bindViewModel()
        viewModel.fetchData()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        searchViewController.searchResultsUpdater = self
        navigationItem.searchController = searchViewController
        navigationItem.hidesSearchBarWhenScrolling = false
        definesPresentationContext = true
    }

    func updateSearchResults(for searchController: UISearchController) {
        let knowledge = viewModel.state.motion pictures
        if let searchText = searchController.searchBar.textual content {
            filteredData = searchText.isEmpty ? knowledge : filteredData
        
            tableView.reloadData()
        }
    }

    non-public func configureTableView() {
        tableView.dm_registerClassWithDefaultIdentifier(cellClass: MovieCell.self)
        tableView.rowHeight = UITableView.automaticDimension

        refreshControl = UIRefreshControl()
        refreshControl?.addTarget(self, motion: #selector(refreshData), for: .valueChanged)
    }

    non-public func bindViewModel() {
        viewModel.updatedState = { [weak self] in
            guard let self else { return }
            DispatchQueue.essential.async {
                self.updateFromViewModel()
            }
        }
    }

    non-public func updateFromViewModel() {
        swap viewModel.state {
        case .loading, .loaded:
            tableView.reloadData()
        case .error:
            showError()
        }
        refreshControl?.endRefreshing()
    }

    non-public func showError() {
        let alertController = UIAlertController(title: "", message: LocalizedString(key: "motion pictures.load.error.physique"), preferredStyle: .alert)
        let alertAction = UIAlertAction(title: LocalizedString(key: "motion pictures.load.error.actionButton"), fashion: .default, handler: nil)
        alertController.addAction(alertAction)
        current(alertController, animated: true, completion: nil)
    }

    @objc non-public func refreshData() {
        viewModel.fetchData()
    }

    @objc non-public func textSizeChanged() {
        tableView.reloadData()
    }

    non-public func configureSearchBar() {

        let searchTextField = searchViewController.searchBar.searchTextField
        searchTextField.attributedPlaceholder = NSAttributedString(string: "Search", attributes: [.font: UIFont.Body.medium, .foregroundColor: UIColor.Text.charcoal])
        searchTextField.font = UIFont(identify: "Poppins-Common", measurement: 16)
        searchTextField.backgroundColor = UIColor(pink: 248 / 255.0, inexperienced: 248 / 255.0, blue: 248 / 255.0, alpha: 1)
        searchTextField.borderStyle = .none
        searchTextField.layer.borderColor = UIColor.black.withAlphaComponent(0.08).cgColor
        searchTextField.layer.borderWidth = 1.0
        searchTextField.layer.cornerRadius = 8

        searchViewController.searchBar.setLeftImage(UIImage(named: "Search"))
        searchViewController.searchBar.barTintColor = .clear
        searchViewController.searchBar.setImage(UIImage(named: "Filter"), for: .bookmark, state: .regular)
        searchViewController.searchBar.showsBookmarkButton = true
        searchViewController.searchBar.delegate = self
        searchViewController.searchBar.tintColor = UIColor.Model.popsicle40
    }
}

// MARK: - UITableViewDataSource
extension MoviesViewController {

    override func tableView(_ tableView: UITableView, numberOfRowsInSection part: Int) -> Int {
        return filteredData.depend
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: MovieCell = tableView.dm_dequeueReusableCellWithDefaultIdentifier()

        let film = filteredData[indexPath.row]
        cell.configure(film)

        return cell
    }

}

// MARK: - UITableViewControllerDelegate
extension MoviesViewController {

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let film = viewModel.state.motion pictures[indexPath.row]
        let viewModel = MoviesDetailsViewModel(film: film, apiManager: APIManager())
        let viewController = MovieDetailsViewController(viewModel: viewModel)
        self.navigationController?.pushViewController(viewController, animated: true)
    }
}

extension MoviesViewController: UISearchBarDelegate {
    func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar) {
        
    }
}

Right here is the screenshot of the end result.

enter image description here

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments