在mapview

时间:2017-05-02 20:51:43

标签: arrays swift annotations mapkit

我一直在寻找解决方案的stackoverflow,但我还没有成功实现它。如果有人能给我一些关于问题所在的提示,那么非常感谢你。这是我到目前为止所拥有的

这是位置类

class Location: NSObject, MKAnnotation {
var title: String?
var coordinate: CLLocationCoordinate2D

init(title: String, coordinate: CLLocationCoordinate2D) {
    self.title = title
    self.coordinate = coordinate
}

显示所有注释的方法。

func displayAllEventsPins() {
    for event in events {
        let address = event.location
        geocoder.geocodeAddressString(address!, completionHandler: { (placemarks: [CLPlacemark]?, error: Error?) -> Void in
            if let placemark = placemarks?.first {
                let eventlat = placemark.location?.coordinate.latitude
                let eventlong = placemark.location?.coordinate.longitude
                let annotation = MKPointAnnotation()
                annotation.title = event.name
                annotation.coordinate = CLLocationCoordinate2D(latitude: eventlat!, longitude: eventlong!)
                self.locations.append(Location(title: annotation.title!, coordinate: annotation.coordinate))
                    for location in self.locations {
                    let pin = MKPointAnnotation()
                    pin.title = location.title
                    pin.coordinate = location.coordinate
                    self.mapView.addAnnotation(pin)
                }
            }
        })
    }

}

已编辑:此处的问题是注释未显示在mapview上。我只能看到当前的位置引脚而已。

已修改:这是我用来删除用户当前位置信息的电话。

extension Search : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    if status == .authorizedWhenInUse {
        locationManager.requestLocation()

    }
}

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    //MARK: remove previous current pin for user location
    mapView.removeAnnotation(newPin)

    let location = locations.last! as CLLocation
    let center = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
    self.currentLocation = location
    let region = MKCoordinateRegion(center: center, span: MKCoordinateSpanMake(0.03, 0.03))
    mapView.setRegion(region, animated: true)
    newPin.coordinate = location.coordinate
    mapView.addAnnotation(newPin)
}
}

以下是viewDidLoad方法中的代码:

 override func viewDidLoad() {
    super.viewDidLoad()

    //MARK:  Request Current Location
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    locationManager.requestAlwaysAuthorization()
    locationManager.requestLocation()
   displayAllEventsPins()
}

1 个答案:

答案 0 :(得分:1)

这对你有用。

顺便说一句,在事件循环中循环遍历您的位置只会添加相同引脚的重复项,这对内存非常不利,并且它不是一件好事。

import UIKit
import MapKit
import Firebase

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var map: MKMapView!

    let locationManager = CLLocationManager()

    var events = Array<Event>()

    var locations = Array<Location>()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        locationManager.requestWhenInUseAuthorization()

        locationManager.startUpdatingLocation()

        locationManager.desiredAccuracy = kCLLocationAccuracyBest

        // This closure gets called once for every event in your database
        getEvents { (event, pin) in

            self.tableView.reloadData()

            if event != nil && pin != nil {

                print(event!)

                self.locations.append(pin!)

                self.events.append(event!)

            } else {

                print("Failed to get event.")
            }
        }
    }

    func getEvents(results: @escaping (_ event: Event?, _ pin:Location?)->()) {

        let ref = FIRDatabase.database().reference().child("Events")

        ref.observe(.childAdded, with: { (snapshot) in

            guard let value = snapshot.value as? Dictionary<String,String> else { return }

            guard let name = value["eventName"],
            let location = value["location"],
            let attending = value["attendance"],
            let dateTime = value["dateTime"],
            let addedByUser = value["addedByUser"] else { return }

            self.getEventPlacemark(address: location, results: { (placemark) in

                if let placemark = placemark {

                    let pin = Location(title: name, coordinate: placemark.coordinate)

                    var distance: Double = -1 // If user location is not avalible, this will stay at -1

                    if let currentLocation = self.locationManager.location?.coordinate {

                        distance = pin.coordinate.distance(to: currentLocation)
                    }

                    let event = Event(id: snapshot.key, name: name, location: location, dateTime: dateTime, addedByUser: addedByUser, attending: attending, distance: distance)

                    results(event, pin)

                    return
                }
            })
        })
    }

    func getEventPlacemark(address:String, results: @escaping (_ placemark: MKPlacemark?)->()){

        let geocoder = CLGeocoder()

        geocoder.geocodeAddressString(address) { (placemarks, error) in

            if let error = error {

                print(error.localizedDescription)

                results(nil)
            }

            if let placemark = placemarks?.first {

                results(MKPlacemark(placemark: placemark))
            }
        }
    }

    func displayAllEvents(){

        self.map.addAnnotations(self.locations)
    }

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        if let userLocation = annotation as? MKUserLocation {

            let view = (mapView.dequeueReusableAnnotationView(withIdentifier: "userLocationPin") as? MKPinAnnotationView) ?? MKPinAnnotationView(annotation: userLocation, reuseIdentifier: "userLocationPin")

            view.pinTintColor = .purple

            view.canShowCallout = true

            return view
        }

        if let pin = annotation as? MKPointAnnotation {

            let view = (mapView.dequeueReusableAnnotationView(withIdentifier: "pin") as? MKPinAnnotationView) ?? MKPinAnnotationView(annotation: pin, reuseIdentifier: "pin")

            view.pinTintColor = .red

            view.canShowCallout = true

            return view
        }

        return nil
    }
}

class Location: NSObject, MKAnnotation {

    var title: String?

    var coordinate: CLLocationCoordinate2D

    init(title: String, coordinate: CLLocationCoordinate2D) {

        self.title = title

        self.coordinate = coordinate
    }
}


struct Event {

    var name: String

    var location: String
}

extension CLLocationCoordinate2D {

    func distance(to: CLLocationCoordinate2D) -> CLLocationDistance {

        return MKMetersBetweenMapPoints(MKMapPointForCoordinate(self), MKMapPointForCoordinate(to))
    }
}

如果您要在上面实施我的代码,则需要从

中删除您的代码
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])

因为您不再需要手动添加图钉。

你能尝试将它放在你的视图中加载功能,而不是运行其他任何东西。这应该在非洲西部设置一个销钉。

  

要注意的是,如果坐标是   CLLocationCoordinate2D(纬度:0,经度:0),引脚出现   在日期线上的Antartica,这是右下角   地图。因此,如果由于某种原因你的坐标是默认的0,0,   你的别针可能坐在那里。

let pin = MKPointAnnotation()

pin.title = "Null Island"

pin.coordinate = CLLocationCoordinate2DMake(0.000001, 0.000001)

self.map.addAnnotation(pin)

这可能就是你的引脚所在。

enter image description here