奇怪的TableView和SearchBar

时间:2018-06-13 09:18:21

标签: swift tableview

我的SearchBar和TableView有一个非常奇怪的问题。 我有一个带有这个SearchBar的MapView,你可以在搜索栏中搜索地名,我用数据库过滤名称,如果名称存在,它将被添加到TableView中。 我可以毫无问题地搜索它,但我有两个奇怪的问题。 如果我在TableView中获得3-4值,如果我搜索第五个值,则不会显示。 我遇到的第二个问题是,如果我得到类似的地名,我点击两个中的一个,如果我第二次尝试研究它,tableview将只显示我之前点击的名称,如果我尝试点击它第三次,我尝试研究它,tableview将不会显示它。 (当我点击TableView上的值时,它会在地图上显示它。)

错误视频:https://streamable.com/e72wn

代码:

extension LocationSearchTable : UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
    //print("updateSearchResults")

    // *When user open the Search Bar and he doesn't type text or the text is very short this code clean the TableView.*
    let searchText = searchController.searchBar.text
    if searchText == nil || searchText!.isEmpty {
        seenNames.removeAll()
        matchingItems.removeAll()
        self.tableView.reloadData()
    }

    guard let mapView = mapView else { return }

    let request = MKLocalSearchRequest()
    request.naturalLanguageQuery = searchText
    request.region = mapView.region
    let search = MKLocalSearch(request: request)

    search.start { response, _ in
        guard let response = response else {
            return
        }

        for (index , name) in response.mapItems.enumerated() {
            let item = response.mapItems[index]
            if(checkIfNameExistInDB(key: String(name.name!)) != nil && !seenNames.contains(name.name!)){
                matchingItems.append(item)
                seenNames.insert(name.name!)
                self.tableView.reloadData()
            }
            else {
                print(name.name!)
            }
        }
}
}
}

TableView代码:

     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
    let selectedItem = matchingItems[indexPath.row].placemark
    cell.textLabel?.text = selectedItem.name
    cell.imageView?.image = imageWithImage(image: UIImage(named: "search_1x")!, scaledToSize: CGSize(width: 20, height: 20))
    cell.detailTextLabel?.text = parseAddress(selectedItem: selectedItem)
    return cell
}

在使用第一个名称的错误后,SearchBar看起来像被阻止,并且没有搜索任何内容

2 个答案:

答案 0 :(得分:1)

matchingItems.removeAllObjects()保留在func updateSearchResults(for searchController: UISearchController)

每当搜索文本发生变化时,您都需要删除对象。

然后匹配对象将添加到数组

答案 1 :(得分:0)

您的第一个问题是由您输入搜索字词时产生的大量请求引起的,因为在键入或删除的每个字符上都会创建并启动新的MKLocalSearch。 为了验证这一点,我把你的代码放在游乐场并测试:

import PlaygroundSupport
import UIKit
import MapKit

PlaygroundPage.current.needsIndefiniteExecution = true

var searches = [MKLocalSearch]()

for i in 1...100 {
    let request = MKLocalSearchRequest()
    request.naturalLanguageQuery = "Via roma n. \(i), Roma"
    let search = MKLocalSearch(request: request)
    search.start { (response, error) in
        guard error == nil else {
            print("request \(i) finished with error \(error!.localizedDescription)")
            return
        }
        guard let _ = response else {
            print("request \(i) finished with no response")
            return
        }

        print("request \(i) completed successfully!")
    }
    searches.append(search)
}

您会看到某些请求已完成且没有错误,对于某些请求,您将获得

The operation couldn’t be completed. (MKErrorDomain error 3.)

MKErrorLoadingThrottled。根据{{​​3}},此错误发生在

  

未加载数据,因为数据限制有效。如果应用程序在短时间内频繁请求数据,则会发生此错误。

此外根据Apple dev

  

每个应用或开发者ID都没有请求限制,因此编写良好的应用程序正常运行应该不会遇到任何问题。但是,在编写效果极差的应用程序中可能会出现限制,从而产生大量请求。

所以最后,你的问题的解决方案可能是延迟搜索请求的开始,直到用户完成输入(你可以使用当用户没有按任何键盘键一段时间时触发的计时器。)

PS:非常重要的是记得取消之前的请求,然后再开始新的请求,否则你会得到不可预见的行为