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

Pass Variables to a new View Controller via a Subclass and Dozens of Map Pins

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

前面的问题不使用子类,在这个例子中,地图上可能有几十个自定义图钉,每个图钉将特定变量传递给新的 ViewController

三个进球:

  1. 将图像添加到自定义注释(见下面的代码)
  2. 我有一个名为 Capital 的子类,我想在 #1 中添加图像,然后创建其他变量来保存将传递给新 SecondViewController 的值,其中包括 (2 ) 标签和一个选择器视图:例如 label1 = "text1", label2 = "text2",然后从包含多个 objects 的数组中抓取一个字符串(即每行的标题选择器)
  3. 一旦用户点击自定义 pin 上的标注按钮,我们将 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   
    }
}

感谢任何帮助

看来你很亲近。在 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.

中配置其控件