2017-01-16 5 views
0

이 앱의 의도는 사용자가 탭 컨트롤러의 한 탭에서 모든 좌표 세트를 입력 할 수있게하고 다른 탭에서 좌표가 핀에 배치되도록하는 것입니다 특수 효과가있는스위프트 배열에 좌표 추가 및지도에 추가

구현하려고 시도한 방법은 입력 좌표를 추가하고 다른 클래스 파일 (mapView 사용)에서 호출 한 전역 배열을 사용하는 것입니다. 배열을 반복하여 핀을 배치하는 데 많은 어려움을 겪었습니다. 무엇이 잘못되었는지 확신 할 수 없습니다.

입력 정보 클래스 파일 :

import UIKit 
import CoreLocation 

var locations: [Dictionary<String, Any>] = [] // here I initialize my array 

class OtherVC: UIViewController { 

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

    @IBOutlet weak var titleTextField: UITextField! 
    var coordinates = [CLLocationCoordinate2D]() 

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



// This IBOutlet takes the coordinate input information from the user 
@IBAction func addToMap(_ sender: Any) { 
    let lat = latitudeField.text! 
    let long = longitudeField.text! 
    let title = titleTextField.text! 
    var location: [String: Any] = ["title": title, "latitude": lat, "longitude": long] 
    locations.append(location) // adding the info to the array 
    let mapVC : MapViewController = MapViewController() 
    mapVC.iterateLocations() 

    } 


} 

지도보기 클래스 파일 :

import UIKit 
import MapKit 
class MapViewController: UIViewController, MKMapViewDelegate { 


    @IBOutlet weak var mapView: MKMapView! 



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

    // this method here iterates through each of the locations in the array 
    func iterateLocations() -> Bool { 
     for location in locations { 

      var momentaryLat = (location["latitude"] as! NSString).doubleValue 
      var momentaryLong = (location["longitude"] as! NSString).doubleValue 
      let annotation = MKPointAnnotation() 
      annotation.title = location["title"] as? String 
      annotation.coordinate = CLLocationCoordinate2D(latitude: momentaryLat as CLLocationDegrees, longitude: momentaryLong as CLLocationDegrees) 
      mapView.addAnnotation(annotation) 
     } 
     return true 
    } 


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

오류가 줄에 팝업 "mapView.addAnnotation (주석)"그것이 전무가 발견되었다고 말과 함께 선택 사항을 풀려고 할 때. 따라서 정보가 주석에 저장되지 않는다는 오류가 있다고 생각합니다. 그러나이 오류가있는 곳을 즉시 알 수는 없습니다.

구현하기가 더 쉬운이 방법의 대안은 환영합니다!

답변

1

1) 사실 MapViewController을 새로 만들고 addToMap 메서드 내부에 로컬 범위가 있습니다. 이 새로운보기 컨트롤러는 프로그래밍 방식으로 만들어지며 UITabBarViewControllerMapViewController 인스턴스와 아무 관련이 없습니다. 그 mapView 콘센트는 nil으로 설정되어 있습니다. 따라서 해당 속성에 액세스하려고하면 암시 적 언 랩핑은 nil이며 앱이 다운 될 수 있습니다. 또한 뷰 컨트롤러 로컬 인스턴스는 addToMap 메서드 끝에 할당이 취소됩니다.

2) 그러므로 UITabBarController을 통해 이미 존재하는 MapViewController에 대한 액세스 권한을 얻으려고합니다. 그러나 사용자가 적어도 한 번 이상지도보기 탭으로 전환하기 전에 mapView 콘센트에 액세스하려고하면 동일한 오류가 표시됩니다. 이는 MapViewController의보기가로드되지 않았기 때문입니다 (필요한 경우에만보기가 필요합니다. 즉,이 경우 사용자가지도보기 탭을 탭하면 표시됩니다). loadViewIfNeeded()에 전화하여보기로드 및 mapView 콘센트 설정을 강제 실행할 수 있습니다.

3) 이전 위치에 새 위치를 추가 할 때마다 addToMap이 호출 될 때마다 모든 위치에서 반복하여 주석을 만듭니다. 이 결과 동일한 주석이 여러 번 맵에 추가됩니다. iterateLocations 메서드를 add(newLocation:[String:Any])과 같이 변경할 수 있으며 사용자 입력에서 마지막으로 얻은 위치 만 전달하면됩니다.

그래서 한가지 해결책은 대체 될 것이다 :

let mapVC : MapViewController = MapViewController()addToMap 내부 :

let mapVC : MapViewController = self.tabBarController!.viewControllers![1] as! MapViewController 
mapVC.loadViewIfNeeded() 
mapVC.add(newLocation:location) 

OtherVC는 인덱스 0이고 MapViewController가 탭보기 컨트롤러의 인덱스는 1이라고 가정. 또한 :

func add(newLocation location:[String:Any]) { 
     let momentaryLat = (location["latitude"] as! NSString).doubleValue 
     let momentaryLong = (location["longitude"] as! NSString).doubleValue 
     let annotation = MKPointAnnotation() 
     annotation.title = location["title"] as? String 
     annotation.coordinate = CLLocationCoordinate2D(latitude: momentaryLat as CLLocationDegrees, longitude: momentaryLong as CLLocationDegrees) 
     mapView.addAnnotation(annotation) 
} 
+0

아 내가 이니까 페이지의 "mapVC을 보자 MapViewController = MapViewController()"를 UITabBarViewController에 의해 제어되는 실제 MapViewController을 참조하지 않습니다. 또한 함수가 반복 될 때마다 동일한 주석을 반복한다는 점을 지적 해 주셔서 감사합니다.그러나 추천을 사용하면 MapView에 주석이 추가되지 않습니다. (하지만 앱이 더 이상 충돌하지 않습니다!) 문제의 원인을 아십니까? – Kevin

+1

다음과 같이 해보는 것이 좋습니다. 1) 맵에 추가 한 직후에 주석의 좌표에 맵을 중앙에 놓습니다. 즉,''self.mapView.centerCoordinate = annotation.coordinate'''가''' 'add'' 메소드를 호출합니다. 2) iOS 9 시뮬레이터를 사용해보십시오. 3) 주석을 추가 한 후 디버거에서 mapView.annotations 속성을 인쇄 해보십시오. 4) 주석이 범위를 벗어 났는지 확인하기 위해 UI 디버거를 시험해보십시오. 위의 도움이 필요하면 알려주세요! – stakri

+0

서쪽 좌표를 음수 좌표로 입력해야한다는 것이 판명되었습니다! self.mapView.centerCoordinate = annotation.coordinate는 그 점을 이해하는 데 도움이되었습니다! – Kevin