在MapView中search注释

我遵循了一个关于在mapViewsearchannotations以及在MKLocalSearchsearch世界的方法的如何search位置使用苹果 MKLocalSearch

但是,我不想用MKLocalSearch进行search,而是search我自己的annotations ,例如我自己添加了这些annotations

 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) 

这是我的代码:

MapViewController.Swift:

 import UIKit import MapKit import CoreLocation protocol HandleMapSearch { func dropPinZoomIn(placemark:MKPlacemark) } class MapViewController: UIViewController,MKMapViewDelegate, CLLocationManagerDelegate,UISearchBarDelegate{ @IBOutlet var mapView: MKMapView! var resultSearchController:UISearchController? = nil var selectedPin:MKPlacemark? = nil @IBAction func MapSearchController(sender: AnyObject) { resultSearchController!.hidesNavigationBarDuringPresentation = false self.resultSearchController!.searchBar.delegate = self presentViewController(resultSearchController!, animated: true, completion: nil) self.resultSearchController!.searchBar.barTintColor = UIColor.blackColor() self.resultSearchController!.searchBar.placeholder = "חפש ברים" self.resultSearchController!.dimsBackgroundDuringPresentation = true self.resultSearchController!.searchBar.sizeToFit() } override func viewDidLoad() { super.viewDidLoad() let locationSearchTable = storyboard!.instantiateViewControllerWithIdentifier("LocationSearchTable") as! LocationSearchTable resultSearchController = UISearchController(searchResultsController: locationSearchTable) resultSearchController?.searchResultsUpdater = locationSearchTable locationSearchTable.mapView = mapView locationSearchTable.handleMapSearchDelegate = self } } } extension MapViewController: HandleMapSearch { func dropPinZoomIn(placemark:MKPlacemark){ // cache the pin selectedPin = placemark // clear existing pins mapView.removeAnnotations(mapView.annotations) let annotation = MKPointAnnotation() annotation.coordinate = placemark.coordinate annotation.title = placemark.name if let city = placemark.locality, let state = placemark.administrativeArea { annotation.subtitle = "(city) (state)" } mapView.addAnnotation(annotation) let span = MKCoordinateSpanMake(0.05, 0.05) let region = MKCoordinateRegionMake(placemark.coordinate, span) mapView.setRegion(region, animated: true) } } 

LocalSearchTable.Swift:

 import UIKit import MapKit class LocationSearchTable : UITableViewController { var matchingItems:[MKMapItem] = [] 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 } } 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")! let selectedItem = matchingItems[indexPath.row].placemark cell.textLabel?.text = selectedItem.name cell.detailTextLabel?.text = parseAddress(selectedItem) 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) } } 

你只要参考这个链接http://www.coderzheaven.com/2016/02/14/mapkit-demo-swift-annotation-custom-annotation-custom-annotation-with-button-search-showing-directions-apple-地图-IOS /

您将了解以下主题

  • 在地图中显示注释。
  • 在地图中显示自定义注释。
  • 在地图中使用自定义button显示自定义注释。

TL; DR

示例项目: https : //github.com/JakubMazur/SO40539590


好的,一开始我会build议你从你的控制器代码中分离数据。 我selectjson格式作为最普遍的一个。 所以:

 [ { "title":"Litzman Bar", "subtitle":"נמל תל אביב 18,תל אביב", "coordinates":{ "lat":32.100668, "lon":34.775192 } }, { "title":"Shalvata", "subtitle":"האנגר 28,נמל תל אביב", "coordinates":{ "lat":32.101145, "lon":34.775163 } }, { "title":"Markid", "subtitle":"אבן גבירול 30,תל אביב", "coordinates":{ "lat":32.074961, "lon":34.781679 } } ] 

这基本上是你的数据库。

现在让我们把它parsing成你的ViewConttroller使用的Array 。 再次,我会build议你将其分割成模型对象,如LocationCoordinate 。 我们来看看它的一个类作为例子:

 class Location: NSObject { var title : String = String() var subtitle : String = String() var coordinates : Coordinate = Coordinate() public class func locationFromDictionary(_ dictionary : Dictionary<String, AnyObject>) -> Location { let location : Location = Location() location.title = dictionary["title"] as! String location.subtitle = dictionary["subtitle"] as! String location.coordinates = Coordinate.coordinateFromDictionary(dictionary["coordinates"] as! Dictionary<String, AnyObject>) return location; } } 

我不会将用于parsingjson文件的代码粘贴到这个对象上,因为这个问题不是这个问题。 你会发现到存储库。

现在让我们把重点放在问题上。

我会build议你不要search注释,而是search你的数据模型,并在需要时重新绘制注释

为了做到这一点(我将使用UISearchBar ):

 func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { self.displayArray = self.locationsDatabase.filter() { return $0.title.contains("i") } 

那么当你像这样一个二传手:

 var displayArray : Array<Location> = [] { didSet { self.mapView .removeAnnotations(self.mapView.annotations) for location in displayArray { let coords : Coordinate = location.coordinates let point = MKPointAnnotation() point.coordinate = CLLocationCoordinate2DMake(CLLocationDegrees(coords.latitude),CLLocationDegrees(coords.longitude)) point.title = location.title point.subtitle = location.subtitle mapView.addAnnotation(point) } } } 

您可以重绘您的注释。 像空search领域,案件敏感性,解雇键盘的边缘情况下,我给你。 但希望你能得到一般的想法。 你可能会认为它是过度工程,但将对象作为一个单独的类和通用格式作为数据input可能在未来受益。

完整的项目: https : //github.com/JakubMazur/SO40539590