2017-02-20 6 views
2

Ich versuche, eine benutzerdefinierte MKPointAnnotation erstellen, um auf einer Kartenansicht zu verwenden. Es sieht ganz so aus, wie die in Apples Fotos verwendet:Swift - Benutzerdefinierte MKPointAnnotation mit Bild

enter image description here

Ich werde eine Reihe von Fotos von einem Server, zusammen mit ihrem Standort wird abruft. Ich möchte dann eine Annotation wie die obige mit dem Bild in der Annotation anzeigen.

Ich habe derzeit ein Programm, das eine normale MKPointAnnotation an der richtigen Koordinate hinzufügen kann, und kann auch das entsprechende Foto vom Server abrufen.

Alles, was ich will ist, meine MKPointAnnotation zu stylen, um genau so auszusehen.

Ich habe versucht, andere Antworten zu folgen, aber ich denke, das ist etwas anders, weil ich jedes Mal ein Bild auf einer Vorlage zeigen möchte.

Antwort

7

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? von MKMapViewDelegate ist die Funktion, die Sie überschreiben müssen.

Sie können "benutzerdefinierte" Ansichten für jede Annotation bereitstellen. Innerhalb dieser Funktion können Sie entweder eine benutzerdefinierte Ansicht (Unterklasse MKAnnotationView) aus der Warteschlange entfernen und benutzerdefinierte Eigenschaften festlegen ODER Sie können eine reguläre MKAnnotationView mit der Eigenschaft image aus der Warteschlange entfernen.

Sie können diese Eigenschaft so einstellen, dass benutzerdefinierte Bilder angezeigt werden. Ich würde sowieso lieber meinen eigenen annotationView verwenden, da Sie benutzerdefinierte Layouts (Labels, imageViews, etc ..) und Themen (Farben, Ebenen, etc ..) hinzufügen können.

Beispiel:

// 
// ViewController.swift 
// Maps 
// 
// Created by Brandon T on 2017-02-20. 
// Copyright © 2017 XIO. All rights reserved. 
// 

import UIKit 
import MapKit 


class ImageAnnotation : NSObject, MKAnnotation { 
    var coordinate: CLLocationCoordinate2D 
    var title: String? 
    var subtitle: String? 
    var image: UIImage? 
    var colour: UIColor? 

    override init() { 
     self.coordinate = CLLocationCoordinate2D() 
     self.title = nil 
     self.subtitle = nil 
     self.image = nil 
     self.colour = UIColor.white 
    } 
} 

class ImageAnnotationView: MKAnnotationView { 
    private var imageView: UIImageView! 

    override init(annotation: MKAnnotation?, reuseIdentifier: String?) { 
     super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 

     self.frame = CGRect(x: 0, y: 0, width: 50, height: 50) 
     self.imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 50)) 
     self.addSubview(self.imageView) 

     self.imageView.layer.cornerRadius = 5.0 
     self.imageView.layer.masksToBounds = true 
    } 

    override var image: UIImage? { 
     get { 
      return self.imageView.image 
     } 

     set { 
      self.imageView.image = newValue 
     } 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 

class ViewController: UIViewController, MKMapViewDelegate { 

    var mapView: MKMapView! 
    var locationManager: CLLocationManager! 

    override func viewDidLoad() { 
     super.viewDidLoad() 


     self.initControls() 
     self.doLayout() 
     self.loadAnnotations() 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    func initControls() { 
     self.mapView = MKMapView() 

     self.mapView.isRotateEnabled = true 
     self.mapView.showsUserLocation = true 
     self.mapView.delegate = self 

     let center = CLLocationCoordinate2DMake(43.761539, -79.411079) 
     let region = MKCoordinateRegionMake(center, MKCoordinateSpanMake(0.005, 0.005)) 
     self.mapView.setRegion(region, animated: true) 
    } 

    func doLayout() { 
     self.view.addSubview(self.mapView) 
     self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true 
     self.mapView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true 
     self.mapView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true 
     self.mapView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true 
     self.mapView.translatesAutoresizingMaskIntoConstraints = false 
    } 

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 
     if annotation.isKind(of: MKUserLocation.self) { //Handle user location annotation.. 
      return nil //Default is to let the system handle it. 
     } 

     if !annotation.isKind(of: ImageAnnotation.self) { //Handle non-ImageAnnotations.. 
      var pinAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "DefaultPinView") 
      if pinAnnotationView == nil { 
       pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "DefaultPinView") 
      } 
      return pinAnnotationView 
     } 

     //Handle ImageAnnotations.. 
     var view: ImageAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: "imageAnnotation") as? ImageAnnotationView 
     if view == nil { 
      view = ImageAnnotationView(annotation: annotation, reuseIdentifier: "imageAnnotation") 
     } 

     let annotation = annotation as! ImageAnnotation 
     view?.image = annotation.image 
     view?.annotation = annotation 

     return view 
    } 


    func loadAnnotations() { 
     let request = NSMutableURLRequest(url: URL(string: "https://i.imgur.com/zIoAyCx.png")!) 
     request.httpMethod = "GET" 

     let session = URLSession(configuration: URLSessionConfiguration.default) 
     let dataTask = session.dataTask(with: request as URLRequest) { (data, response, error) in 
      if error == nil { 

       let annotation = ImageAnnotation() 
       annotation.coordinate = CLLocationCoordinate2DMake(43.761539, -79.411079) 
       annotation.image = UIImage(data: data!, scale: UIScreen.main.scale) 
       annotation.title = "Toronto" 
       annotation.subtitle = "Yonge & Bloor" 


       DispatchQueue.main.async { 
        self.mapView.addAnnotation(annotation) 
       } 
      } 
     } 

     dataTask.resume() 
    } 
} 
+0

Sorry, ich bin ein bisschen verwirrt. Wie erstelle ich die benutzerdefinierte Anmerkung mit dieser Implementierung? – user2397282

+0

ImageAnnotationView ist eine benutzerdefinierte Anmerkungsansicht. Sie müssen es anpassen, wie Sie wollen. Stellen Sie den Hintergrund auf Weiß, fügen Sie das Bild usw. hinzu. – Brandon

+0

Oh ich sehe, also werde ich keinen MKPointAnnotation verwenden? – user2397282

1

Wenn Sie in der Karte viele Lage gesetzt werden sollen mit verschiedenen Bildern diesen Code verwenden:

@Brandon, Danke

@objc func loadAnnotations() { 

    for item in locations{ 
     DispatchQueue.main.async { 
      let request = NSMutableURLRequest(url: URL(string: "<YourPictureUrl>")!) 
      request.httpMethod = "GET" 
      let session = URLSession(configuration: URLSessionConfiguration.default) 
      let dataTask = session.dataTask(with: request as URLRequest) { (data, response, error) in 
       if error == nil { 

        let annotation = ImageAnnotation() 
        annotation.coordinate = CLLocationCoordinate2DMake(Double(item["pl_lat"] as! String)!, 
                     Double(item["pl_long"] as! String)!) 
        annotation.image = UIImage(data: data!, scale: UIScreen.main.scale) 
        annotation.title = "T" 
        annotation.subtitle = "" 
        DispatchQueue.main.async { 
         self.mapView.addAnnotation(annotation) 
        } 
       } 
      } 

      dataTask.resume() 
     } 
    } 
} 
Verwandte Themen