在MapView中搜索注释

New*_*ons 5 iphone annotations mkmapview ios swift

我也跟着 怎么到搜寻-位置-使用-苹果- mapkit关于搜索annotationsmapView 和其在世界各地与搜索MKLocalSearch.

但是,我不想搜索,MKLocalSearch但搜索我自己,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)
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

Jak*_*kub 0

长话短说

\n\n

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

\n\n
\n\n

好的,首先我建议您将数据与控制器代码分开。我选择json格式作为最通用的格式。所以:

\n\n
[\n   {\n      "title":"Litzman Bar",\n      "subtitle":"\xd7\xa0\xd7\x9e\xd7\x9c \xd7\xaa\xd7\x9c \xd7\x90\xd7\x91\xd7\x99\xd7\x91 18,\xd7\xaa\xd7\x9c \xd7\x90\xd7\x91\xd7\x99\xd7\x91",\n      "coordinates":{\n         "lat":32.100668,\n         "lon":34.775192\n      }\n   },\n   {\n      "title":"Shalvata",\n      "subtitle":"\xd7\x94\xd7\x90\xd7\xa0\xd7\x92\xd7\xa8 28,\xd7\xa0\xd7\x9e\xd7\x9c \xd7\xaa\xd7\x9c \xd7\x90\xd7\x91\xd7\x99\xd7\x91",\n      "coordinates":{\n         "lat":32.101145,\n         "lon":34.775163\n      }\n   },\n   {\n      "title":"Markid",\n      "subtitle":"\xd7\x90\xd7\x91\xd7\x9f \xd7\x92\xd7\x91\xd7\x99\xd7\xa8\xd7\x95\xd7\x9c 30,\xd7\xaa\xd7\x9c \xd7\x90\xd7\x91\xd7\x99\xd7\x91",\n      "coordinates":{\n         "lat":32.074961,\n         "lon":34.781679\n      }\n   }\n]\n
Run Code Online (Sandbox Code Playgroud)\n\n

这基本上就是您的数据库。

\n\n

现在让我们将其解析为Array在您的ViewConttroller. 我再次建议您将其拆分为 Model 对象,例如LocationCoordinate。让我们看一下其中的一个类作为示例:

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

我不会将用于解析json文件的代码粘贴到该对象,因为这不是这个问题的目的。您将在存储库中找到。

\n\n

现在让我们集中讨论问题。

\n\n

我建议您不要搜索注释,而是搜索您的数据模型并在需要时重绘注释

\n\n

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

\n\n
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {\n    self.displayArray = self.locationsDatabase.filter() {\n        return $0.title.contains("i")\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后当你像这样重写 setter 时:

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

您可以重新绘制注释。我将边缘情况留给您,例如空搜索字段、区分大小写、关闭键盘。但希望您能了解总体思路。您可能认为它是过度设计的,但将对象作为单独的类和通用格式作为数据输入可能会在将来受益。

\n\n

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

\n