首页 > 解决方案 > Swift 表视图和搜索控制器 didSelectRowAt 索引超出范围

问题描述

在 Swift 中,我使用 SearchController 和 TableView 以及下面的搜索 API。

https://developers.giphy.com/docs/api/endpoint#search

api.giphy.com/v1/gifs/search

当我输入 SearchController 字段时,TableView 通常会重新加载(出现自动完成的搜索关键字)。但是当我选择 TableView 的行时,在某些情况下发生了“索引超出范围”错误(在我的 ViewModel 中),我无法弄清楚是什么原因。

func searchKeyword(indexPath: Int) -> String?ViewModel 中发生错误行

这是我的代码。

视图控制器

extension ViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let count = self.viewModel?.resultsCount() else { return 0 }
        return count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = searchTableView.dequeueReusableCell(withIdentifier: "CellID", for: indexPath) as? searchTableViewCell else { return UITableViewCell() }
        guard let result = self.viewModel?.selectedKeyword(at: indexPath.row) else { return UITableViewCell() }
        cell.configureCell(result: result.name)
        return cell
    }

}

extension ViewController: UISearchResultsUpdating {
    func updateSearchResults(for searchController: UISearchController) {
        guard let text = searchController.searchBar.text?.lowercased() else { return }
        self.viewModel?.fetchKeywords(searchKeyword: text)
        self.searchTableView.reloadData()
    }
}

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let nextViewController = self.storyboard?.instantiateViewController(withIdentifier: "NextViewControllerID") as? NextViewController else { return }
        guard let result = self.viewModel?.searchKeyword(indexPath: indexPath.row) else { return }
        nextViewController.showNextViewController(with: NextViewModel(keyword: result))
        self.navigationController?.pushViewController(nextViewController.show, animated: true)
    }
}

extension ViewController: UISearchResultsUpdating {
    func updateResults(for searchController: UISearchController) {
        guard let text = searchController.searchBar.text?.lowercased() else { return }
        self.viewModel?.fetchKeywords(searchKeyword: text)
        self.searchResults.reloadData()
    }
}

视图模型

func fetchKeywords(searchKeyword: String) {
    self.useCase.fetchKeywords(searchKeyword: searchKeyword, paginationCount: 5) { error, result in
        if let error = error {
            self.error = error
        }
        if let result = result {
            self.results = result.searchKeywords
        }
    }
}

func resultsCount() -> Int {
    guard let count = self.results?.count else { return 0 }
    return count
}

// Fatal error: Index out of range
func searchKeyword(indexPath: Int) -> String? {
    guard let results = results else { return nil }
    return results[indexPath].name
}

func selectedKeyword(at indexPath: Int) -> Keyword? {
    guard let results = self.results else { return nil }
    return results[indexPath]
}

标签: swifttableviewuisearchcontroller

解决方案


推荐阅读