UISearchBar搜索结果跳转DetailVC异常问题求助
问题原因分析
你遇到的问题核心在于跳转时获取选中行的逻辑错误:当点击搜索结果的TableView时,你在prepare(for:)方法里取的是当前控制器的self.tableView的选中行,但搜索结果的TableView是searchResultsController.tableView,并非当前控制器的TableView。如果之前总列表的第一项被选中过(或者未取消选中状态),self.tableView.indexPathForSelectedRow就会一直指向第一项的索引,导致无论点击哪个搜索结果,都跳转到总列表的第一项。
解决方案
我们可以直接在点击cell时把对应的模型对象传递给Segue,避免依赖TableView的选中状态,具体步骤如下:
1. 修改didSelectRowAt方法,传递正确的模型对象
在点击cell时,先判断是哪个TableView被点击,取出对应的模型,然后把这个模型作为sender参数传给performSegue:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let selectedItem: Indications // 判断点击的是总列表还是搜索结果列表 if tableView == self.tableView { selectedItem = myData[indexPath.row] } else { selectedItem = resultArray[indexPath.row] } print(selectedItem.name) // 把选中的模型对象作为sender传递 performSegue(withIdentifier: "SegueToDetail", sender: selectedItem) }
2. 修改prepare(for:)方法,直接从sender获取模型
不再依赖TableView的选中行,直接从sender参数里取出之前传递的模型对象:
override func prepare(for segue: UIStoryboardSegue,sender: Any?){ if segue.identifier == "SegueToDetail" { let dest = segue.destination as? DetailVC // 从sender中取出选中的模型 dest?.data = sender as? Indications } }
额外优化建议(非必须但推荐)
搜索结果的TableView目前是直接创建UITableViewCell(),没有使用复用机制,在数据量大时会影响性能。可以在viewDidLoad里注册复用cell:
override func viewDidLoad() { super.viewDidLoad() // ... 其他原有代码 // 注册搜索结果的cell复用标识符 searchResultsController.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "SearchResultCell") }
然后在cellForRowAt方法里修改搜索结果的cell创建逻辑:
else { let cell = tableView.dequeueReusableCell(withIdentifier: "SearchResultCell", for: indexPath) let row = indexPath.row cell.textLabel?.text = resultArray[row].name return cell }
这样修改后,点击搜索结果的任意项就能正确跳转到对应的DetailVC了。
内容的提问来源于stack exchange,提问作者Dan Li
相关产品推荐
相关产品推荐

