2016-12-23 12 views
4

Я пытаюсь создать приложение карты, которое может принимать пользовательские входы координат широты и долготы, которые при вводе будут помещать вывод на карту на другой вкладке. My FirstVC состоит из кнопки «Добавить местоположения», которая переходит в «OtherVC», которую пользователь может ввести в координаты. SecondVC состоит из MapView. Моя первоначальная идея состоит в том, чтобы иметь определенный массив координат, и любые новые координаты будут добавлены к этому массиву. Выполнение - это то, чего мне не хватает, потому что я не уверен, как передать этот массив в MapView. Вот то, что я до сих пор:Swift MKMapViewDelegate - Передача координат между диспетчерами вида

Для ввода координат:

import UIKit 
import CoreLocation 

class OtherVC: UIViewController { 

@IBOutlet weak var latitudeField: UITextField! 
@IBOutlet weak var longitudeField: UITextField! 

var coordinates = [CLLocationCoordinate2D]() 

override func viewDidLoad() { 
    super.viewDidLoad() 

} 


@IBAction func addToMap(_ sender: Any) { 
    let lat = Double(latitudeField.text!) 
    let long = Double(longitudeField.text!) 

    self.coordinates.append(CLLocationCoordinate2D(latitude: lat!, longitude: long!)) 
} 




} 

Для MapView:

import UIKit 
import MapKit 
class MapViewController: UIViewController, MKMapViewDelegate { 
@IBOutlet weak var mapView: MKMapView! 



var coordinates = [CLLocationCoordinate2D]() { 
    didSet { 
     // Update the pins 
     // Since it doesn't check for which coordinates are new, it you go back to 
     // the first view controller and add more coordinates, the old coordinates 
     // will get a duplicate set of pins 
     for (index, coordinate) in self.coordinates.enumerated() { 
      let annotation = MKPointAnnotation() 
      annotation.coordinate = coordinate 
      annotation.title = "Location \(index)" 

      mapView.addAnnotation(annotation) 
     } 
    } 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    mapView.delegate = self 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 
    let identifier = "pinAnnotation" 
    var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView 

    if annotationView == nil { 
     annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) 
     annotationView?.canShowCallout = true 
    } 

    annotationView?.annotation = annotation 
    return annotationView 
} 
} 

enter image description here

ответ

2

Я думаю, что вам нужно, это получить второе ViewController MapViewController с вашего tabBarController, а затем передать массив координат, поэтому в вашем приложении AddToMap замените его

@IBAction func addToMap(_ sender: Any) { 
     let lat = Double(latitudeField.text!) 
     let long = Double(longitudeField.text!) 

     self.coordinates.append(CLLocationCoordinate2D(latitude: lat!, longitude: long!)) 
     //here we pass the coordinate array to mapViewController 
     if let mapViewController = self.tabBarController?.viewControllers?[1] as? MapViewController 
     { 
      mapViewController.coordinates = self.coordinates 
     } 
    } 

Вам нужно также добавить навигацию контроллер, как на картинке enter image description here

Я надеюсь, что это поможет вам

+0

Я добавил оператор break в оператор if-let, и похоже, что он запускает и передает координаты. Тем не менее, я получаю сообщение об ошибке «mapView.addAnnotation (annotation)», получая координаты в mapViewController. Не совсем уверен, в чем проблема. – Kevin

+0

Можете ли вы опубликовать свою ошибку ?, помните, что CLLocation2D не является номером с плавающей точкой, который вы должны проверить, является ли он действительным, я могу улучшить свой ответ, если вы хотите –

+0

Я получаю сообщение об ошибке «Тема 1: EXC_BAD_INSTRUCTION» .. Может ли это быть связано? тип номера в ClLocation2D? – Kevin

1

Вообще говоря, я только использовать метод непосредственно передавая данные от одного ViewController к следующий, если есть родительские отношения с дочерними элементами, и я могу сделать это в файле prepareForSegue или в режиме ожидания (от ребенка к родительскому). В противном случае я думаю, что лучше использовать модель подписчика издателя с уведомлением. Когда ваши скоординировать изменения проводки Уведомления:

NotificationCenter.default.post(name: NSNotification.Name("MapViewController.coordinate.updated"), object: self, userInfo: nil) 

Теперь любой, кто заботится о координатах MapViewController постоянно меняющихся можно слушать:

override func viewDidLoad() { 
    super.viewDidLoad() 
    NotificationCenter.default.addObserver(self, selector: #selector(coordinateUpdated), name: NSNotification.Name("coordinate.updated"), object: nil) 
} 

deinit { 
    NotificationCenter.default.removeObserver(self) 
} 

@objc private func coordinateUpdated(notification: Notification) { 
    if let source = notification.object as? MapViewController { 
     print(source.coordinates) 
    } 
} 

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