通过子类和数十个映射引脚将变量传递给新的视图控制器

时间:2017-09-26 20:03:53

标签: ios swift variables mkmapview viewcontroller

我有一些活动部件,我似乎无法拼接在一起,希望它非常简单。

之前的问题不使用子类,在此示例中,地图上可能有数十个自定义引脚,每个引脚都将特定变量传递给新的ViewController

三个目标:

  1. 将图像添加到自定义注释(请参阅下面的代码)
  2. 我有一个名为Capital的子类,我想在#1中添加图像,然后创建其他变量来保存将传递给包含(2)标签的新SecondViewController的值和Picker View:例如label1 =“text1”,label2 =“text2”,然后从包含多个对象的数组中获取一个字符串(即Picker每行的标题)
  3. 用户点击自定义图钉上的标注按钮后,我们将ViewController推送到名为SecondViewController的新视图控制器,并指定附加到其上的子类Capital的值自定义图钉已被点击到SecondViewController
  4. 中的新标签和选择器视图

    到目前为止,这是我的代码:

    名为Capital.swift

    的子类
    import MapKit
    import UIKit
    
    class Capital: NSObject, MKAnnotation {
        var title: String?
        var coordinate: CLLocationCoordinate2D
        var info: String
    
        // here we would add the custom image in Goal #1
        // here we would add the (2) values for label1 and label2 in Goal #2
        // here we would add the array that contains multiple object in Goal #2
    
        init(title: String, coordinate: CLLocationCoordinate2D, info: String) {
            self.title = title
            self.coordinate = coordinate
            self.info = info
    
         // add additional lines as needed
    
        }
    }
    

    以下是ViewController.swift

    的代码
    import MapKit
    import UIKit
    
    class ViewController: UIViewController, MKMapViewDelegate {
    
        @IBOutlet var mapView: MKMapView!
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let london = Capital(title: "London", coordinate: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), info: "Home to the 2012 Summer Olympics.")
            let oslo = Capital(title: "Oslo", coordinate: CLLocationCoordinate2D(latitude: 59.95, longitude: 10.75), info: "Founded over a thousand years ago.")
            let paris = Capital(title: "Paris", coordinate: CLLocationCoordinate2D(latitude: 48.8567, longitude: 2.3508), info: "Often called the City of Light.")
            let rome = Capital(title: "Rome", coordinate: CLLocationCoordinate2D(latitude: 41.9, longitude: 12.5), info: "Has a whole country inside it.")
            let washington = Capital(title: "Washington DC", coordinate: CLLocationCoordinate2D(latitude: 38.895111, longitude: -77.036667), info: "Named after George himself.")
    
            mapView.addAnnotations([london, oslo, paris, rome, washington])
        }
    
        func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    
            let identifier = "Capital"
            if annotation is Capital {
                if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) {
                    annotationView.annotation = annotation
                    return annotationView
                } else {
                    let annotationView = MKPinAnnotationView(annotation:annotation, reuseIdentifier:identifier)
                    annotationView.isEnabled = true
                    annotationView.canShowCallout = true
    
                    let btn = UIButton(type: .detailDisclosure)
                    annotationView.rightCalloutAccessoryView = btn
                    //annotationView.image = UIImage(named: "#imageLiteral(resourceName: ",pin,")")
                return annotationView
             }
        }
        return nil
    }
    

    在这里,我们添加了特定于所按城市的自定义标注变量,并将这些变量推送到SecondViewController

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        let capital = view.annotation as! Capital
        let placeName = capital.title
        let placeInfo = capital.info
    
        //Add custom image + (2) labels + and the array that contains multiple objects to be passed to the Picker 'view in the SecondViewController
    
        // Upon the User tapping the above button we push all the variables stored in Capital attached to the current city pin that was pressed to the new SecondViewController
    
        // Send the View Controller to the SecondViewController programically
    
        let SecondViewController = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController")
        self.show(SecondViewController!, sender: nil)       
    }
    

    以下是SecondViewController

    的代码
    import UIKit
    class SecondViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
        @IBOutlet weak var pickerView: UIPickerView!
        var cityName = 0
    
        //the values here are pulled from the custom pin that was pressed in the previous ViewController
    
        var Array = ["object1 from custom pin","object2 from custom pin,","object3 from custom pin"]
    
        @IBOutlet weak var label1: UILabel!
        @IBOutlet weak var label2: UILabel!
        override func viewDidLoad() {
            super.viewDidLoad()
            pickerView.delegate = self
            pickerView.dataSource = self
        }
    
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            return Array[row]
        }
    
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return Array.count
        }
    
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
    
        @IBAction func submit(_ sender: Any) {
            if (cityName == 0){
                label1.text = "object1 from custom pin"
            }
                else if(cityName == 1){
                label1.text = "object2 from custom pin"
            }
            else{
                label1.text = "object3 from custom pin"
    
                // continued...
            }
        }
    
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            cityName = row   
        }
    }
    

    感谢任何帮助

1 个答案:

答案 0 :(得分:1)

您似乎非常接近。在calloutAccessoryControlTapped,您可以获得地名和信息。我假设你要传递给第二个视图控制器,所以在你show之前继续这样做:

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
    let capital = view.annotation as! Capital
    let placeName = capital.title
    let placeInfo = capital.info

    let secondViewController = sUIKeyInputUpArrowtoryboard!.instantiateViewController(withIdentifier: "SecondViewController") // I'm not sure why you're not just doing `storyboard.instantiateViewController(...); do you really have multiple storyboards floating around?
    secondViewController.placeName = placeName
    secondViewController.placeInfo = placeInfo
    show(secondViewController, sender: self)  
}

当然,这假设您的第二个视图控制器具有placeNameplaceInfo属性,例如

class SecondViewController {

    var placeName: String!
    var placeInfo: String!

    override func viewDidLoad() {
        // use placeName and placeInfo to populate UI controls as necessary
    } 
}
但是,我承认,你的问题有很多不相关的代码很难理解,所以它并不清楚你需要做什么。但这个想法很清楚,calloutAccessoryControlTapped应该

  • 找出需要传递给下一个视图控制器的内容;
  • 实例化该视图控制器;
  • 在下一个视图控制器中设置适当的属性;
  • 然后show它;和
  • 第二个视图控制器应该使用您在前面的视图控制器中设置的任何属性来配置它的UI。

注意,第一个视图控制器中的calloutAccessoryControlTapped无法直接更新第二个视图控制器中的UI控件(因为该视图控制器的控件尚未连接到故事板中的插座),而是只传递第二个视图控制器需要的任何数据。然后,第二个视图控制器将在其viewDidLoad

中配置其控件