2017-02-20 54 views
2

Я пытаюсь создать пользовательский MKPointAnnotation для использования на карте. Он очень похож на тот, используемый в фотографиях от Apple:Swift - Custom MKPointAnnotation с изображением

enter image description here

Я буду извлечения количество фотографий с сервера, а также их расположение. Затем я хочу отобразить аннотацию, подобную приведенной выше, с изображением внутри аннотации.

В настоящее время у меня есть программа, которая может добавить нормальный MKPointAnnotation с правой координатой и также может получить соответствующую фотографию с сервера.

Все, что я хочу, это стиль моего MKPointAnnotation, чтобы выглядеть именно так.

Я пробовал другие ответы, но я думаю, что это немного отличается, потому что я хочу показывать изображение на шаблоне каждый раз.

ответ

7

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? от MKMapViewDelegate - это функция, которую вам необходимо переопределить.

Он позволяет вам предоставлять «пользовательские» виды для каждой аннотации. В рамках этой функции вы можете либо удалить особый вид (подкласс MKAnnotationView), либо установить пользовательские свойства, либо вы можете удалить обычную MKAnnotationView, которая имеет свойство image.

Вы можете установить это свойство для отображения пользовательских изображений. Я бы предпочел использовать свой собственный annotationView в любом случае, так как вы можете добавить пользовательские макеты (метки, изображения и т. Д.) И темы (цвета, слои и т. Д.).

Пример:

// 
// 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

К сожалению, я немного смущенный. Как создать пользовательскую аннотацию с этой реализацией? – user2397282

+0

ImageAnnotationView - это настраиваемый аннотация. Вы должны настроить его, как хотите. Установите его на белый, добавьте изображение и т. Д. – Brandon

+0

О, я вижу, поэтому я не буду использовать MKPointAnnotation? – user2397282

1

Если вы хотите установить в карте много места с различными фотографиями, используйте этот код:

@Brandon, спасибо

@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() 
     } 
    } 
}