在我的项目中,我有一个带有很多注释的 mapView,我想向 map 添加一个搜索功能,这样我就可以搜索这些注释并快速找到我想要的注释。
我按照我在网上找到的教程进行操作,但它在全局范围内搜索 (MKLocalSearch) 而不是注释。
我尝试寻找教程\帮助解决我的问题,但很长一段时间我都得不到任何帮助。 这是我的搜索代码:
我做了这些注释:
let LitzmanLocation = CLLocationCoordinate2DMake(32.100668,34.775192)
// Drop a pin
let Litzman = MKPointAnnotation()
Litzman.coordinate = LitzmanLocation
Litzman.title = "Litzman Bar"
Litzman.subtitle = "נמל תל אביב 18,תל אביב"
mapView.addAnnotation(Litzman)
let ShalvataLocation = CLLocationCoordinate2DMake(32.101145,34.775163)
// Drop a pin
let Shalvata = MKPointAnnotation()
Shalvata.coordinate = ShalvataLocation
Shalvata.title = "Shalvata"
Shalvata.subtitle = "האנגר 28,נמל תל אביב"
mapView.addAnnotation(Shalvata)
let MarkidLocation = CLLocationCoordinate2DMake(32.074961,34.781679)
// Drop a pin
let Markid = MKPointAnnotation()
Markid.coordinate = MarkidLocation
Markid.title = "Markid"
Markid.subtitle = "אבן גבירול 30,תל אביב"
mapView.addAnnotation(Markid)
目前我的搜索:
map View Controller :
//All my Map code is here
}
}
}
extension MapViewController: HandleMapSearch {
func dropPinZoomIn(placemark:MKPlacemark){
// cache the pin
selectedPin = placemark
// clear existing pins
let annotation = MKPointAnnotation()
annotation.coordinate = placemark.coordinate
annotation.title = placemark.name
if let _ = placemark.locality,
let _ = placemark.administrativeArea {
annotation.subtitle = ""
}
mapView.addAnnotation(annotation)
let span = MKCoordinateSpanMake(0.01, 0.01)
let region = MKCoordinateRegionMake(placemark.coordinate, span)
mapView.setRegion(region, animated: true)
}
}
搜索表:
import UIKit
import MapKit
class LocationSearchTable : UITableViewController {
var matchingItems = [CustomAnnotations]()
var mapView: MKMapView? = nil
var handleMapSearchDelegate:HandleMapSearch? = nil
func parseAddress(selectedItem:MKPlacemark) -> String {
// put a space between "4" and "Melrose Place"
let firstSpace = (selectedItem.subThoroughfare != nil && selectedItem.thoroughfare != nil) ? " " : ""
// put a comma between street and city/state
let comma = (selectedItem.subThoroughfare != nil || selectedItem.thoroughfare != nil) && (selectedItem.subAdministrativeArea != nil || selectedItem.administrativeArea != nil) ? ", " : ""
// put a space between "Washington" and "DC"
let secondSpace = (selectedItem.subAdministrativeArea != nil && selectedItem.administrativeArea != nil) ? " " : ""
let addressLine = String(
format:"%@%@%@%@%@%@%@",
// street number
selectedItem.subThoroughfare ?? "",
firstSpace,
// street name
selectedItem.thoroughfare ?? "",
comma,
// city
selectedItem.locality ?? "",
secondSpace,
// state
selectedItem.administrativeArea ?? ""
)
return addressLine
}
func search(keywords:String) {
self.matchingItems.removeAll()
for annotation in self.mapView!.annotations {
if annotation.isKindOfClass(CustomAnnotations) {
//Just an example here for searching annotation by title, you could add other filtering actions else.
if (annotation.title??.rangeOfString(keywords) != nil) {
self.matchingItems.append(annotation as! CustomAnnotations)
}
}
}
self.tableView.reloadData()
}
}
extension LocationSearchTable : UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
guard let mapView = mapView,
let searchBarText = searchController.searchBar.text else { return }
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = searchBarText
request.region = mapView.region
let search = MKLocalSearch(request: request)
search.startWithCompletionHandler { response, _ in
guard let response = response else {
return
}
self.matchingItems = response.mapItems
self.tableView.reloadData()
}
}
}
extension LocationSearchTable {
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return matchingItems.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("MapSearchCell", forIndexPath: indexPath)
let selectedItem = matchingItems[indexPath.row]
cell.textLabel?.text = selectedItem.title
cell.detailTextLabel?.text = selectedItem.subtitle
return cell
}
}
extension LocationSearchTable {
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedItem = matchingItems[indexPath.row]//.placemark
handleMapSearchDelegate?.dropPinZoomIn(selectedItem)
dismissViewControllerAnimated(true, completion: nil)
}
}
我的问题是如何使用 MKLocalSearch 将其转换为仅搜索我的注释而不是搜索全世界。
我是一名使用 swift 3 和 Xcode 8 的初学者
谢谢你的帮助。
最佳答案
如果您真的不想搜索整个 map ,您应该将 MKLocalSearch
完全排除在外。您可以使用 MKLocalSearchRequest.region
选择给定区域的优先级,但您实际上无法限制搜索。相反,您应该遍历 MKMapView
的 annotations
变量。
extension String {
func caseInsensitiveSearch(_ string: String) -> Bool {
if self.lowercased().range(of: string.lowercased()) != nil {
return true;
} else {
return false;
}
}
}
extension MKMapView {
func searchForCustomAnnotation(like query: String) -> [MyCustomAnnotationClass] {
let allAnnotations = self.annotations;
return allAnotations.filter { annotation in
if let customAnnotation = annotation as? MyCustomAnnotationClass {
return customAnnotation.title.caseInsensitiveSearch(query);
}
}
}
}
编辑:我刚刚注意到你说你使用的是 Swift 2.3,我的代码是 Swift 3。如果你使用的是 Swift 2.3,你应该将 String.caseInsensitiveSearch
方法更改为:
extension String {
func caseInsensitiveSearch(_ string: String) -> Bool {
if self.lowercaseString.rangeOfString(string.lowercaseString) != nil {
return true;
} else {
return false;
}
}
}
然后,您可以在 MKMapView
上使用 searchForCustomAnnotation
来获取标题包含您的搜索查询的所有注释的列表。
您的代码如下所示:
extension LocationSearchTable: UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
guard let mapView = mapView,
let searchBarText = searchController.searchBar.text else { return }
self.matchingItems = mapView.searchForCustomAnnotation(like: searchBarText);
self.tableView.reloadData()
}
}
}
关于swift - 在 mapView 中搜索特定的注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43124271/