我的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看起来像被阻止,并且没有搜索任何内容
答案 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:非常重要的是记得取消之前的请求,然后再开始新的请求,否则你会得到不可预见的行为