Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何在Swift 3.0中通过Segue从子类传递变量和对象_Ios_Iphone_Swift_Mapkit_Segue - Fatal编程技术网

Ios 如何在Swift 3.0中通过Segue从子类传递变量和对象

Ios 如何在Swift 3.0中通过Segue从子类传递变量和对象,ios,iphone,swift,mapkit,segue,Ios,Iphone,Swift,Mapkit,Segue,这是我的设置:ViewController->SecondViewControoler 三个目标: 将图像添加到自定义注释(请参见下面的代码) 我有一个名为“Capital”的子类,我想在#1中添加图像,然后创建其他变量来保存值,这些值将传递给一个新的SecondViewController,其中包括(2)个标签和一个选择器视图:例如label1=“text1”,label2=“text2”,然后从包含多个对象的数组中获取一个字符串(即选择器每行的标题) 用户点击自定义pin上的callout按

这是我的设置:ViewController->SecondViewControoler

三个目标:

  • 将图像添加到自定义注释(请参见下面的代码)
  • 我有一个名为“Capital”的子类,我想在#1中添加图像,然后创建其他变量来保存值,这些值将传递给一个新的SecondViewController,其中包括(2)个标签和一个选择器视图:例如label1=“text1”,label2=“text2”,然后从包含多个对象的数组中获取一个字符串(即选择器每行的标题)
  • 用户点击自定义pin上的callout按钮后,我们将ViewController推送到名为“SecondViewController”的新ViewController,并分配附加到自定义pin的子类“Capital”的值,该自定义pin被点击到SecondViewController中的新标签和选择器视图
  • 以下是我迄今为止的代码:

    名为“Capital.swift”的子类

    这是我的ViewController代码。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
    
        }
    }
    
    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 ViewController: 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"
    
    继续

        }
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        cityName = row   
        }
    }
    

    感谢所有帮助

    利用Rob的建议,但是在sender中传递
    大写字母
    对象而不是视图,您的Callout AccessoryControlTapped可能如下所示:

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        guard let capital = view.annotation as? Capital else { return }
        performSegue(withIdentifier: "segue1", sender: capital)
    }
    
    func prepare(for segue: UIStoryboardSegue, 
          sender: Any?) {
        guard let destination = segue.destination as? SecondViewController,
            let capital = sender as? Capital else { return }
        destination.capital = capital //Assuming SecondViewController has a capital property
    }
    

    根据Rob的建议,但在sender中传递
    大写
    对象而不是视图,您的Callout AccessoryControlTapped可能如下所示:

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        guard let capital = view.annotation as? Capital else { return }
        performSegue(withIdentifier: "segue1", sender: capital)
    }
    
    func prepare(for segue: UIStoryboardSegue, 
          sender: Any?) {
        guard let destination = segue.destination as? SecondViewController,
            let capital = sender as? Capital else { return }
        destination.capital = capital //Assuming SecondViewController has a capital property
    }
    

    创建对要在其中向目标类传递数据的类的引用

        `let vc = self.storyboard!.instantiateViewController(withIdentifier: "Class Identifier") as! YourDestinationClass`
    

    然后,您可以使用
    vc
    创建一个类引用,将数据传递到目标类,从而访问
    YourDestinationClass
    中的所有对象

        `let vc = self.storyboard!.instantiateViewController(withIdentifier: "Class Identifier") as! YourDestinationClass`
    
    然后,您将可以使用
    vc

  • 另一个选择是打电话

    "func performSegue(withIdentifier identifier: String, sender: Any?)"
    
    这将触发从ViewController到 SecondViewController。这是您希望在情节提要ie中保持在ViewController之间移动的代码,您控制从ViewController拖动到SecondViewController以创建一个segue,并为其提供唯一id

  • 每个UIViewController(的子类)都继承一个函数

    "func prepare(for segue: UIStoryboardSegue, sender: Any?)"
    
    系统将调用它,您可以在此处添加 如名称所示,实施前应准备好所需的一切 执行一个特定的序列。此时将执行下一个序列 ViewController已从情节提要加载到内存中(但是 尚未开始显示)。和的“segue”*参数
    “准备(对于segue:UIStoryboardSegue,发送方:Any?)”
    实际上有一个 属性“destination”,它实际上是下一个ViewController

    但要小心,因为您可能会有超过1段 ViewController到不同的下一个ViewController。
    因此
    “segue.destination”
    可能不是您想要的SecondViewController,如果 您有多个segue设置。因为系统调用
    “准备(对于segue:UIStoryboardSegue,发送方:Any?)”
    对于每个 继续离开此当前ViewController。请确保检查
    “segue.identifier”
    以确保后续代码正在处理 和你想象的一样

  • 现在你终于可以做你的标题问题了。 使用指向SecondViewController的指针,您可以自由设置任何 它拥有的财产,这是你的资本的特殊情况 对象。要完整循环,请使用
    “performsgue(带标识符:字符串,发件人:任何?)*
    “准备(对于segue:UIStoryboardSegue,sender:Any?)”
    实际上是 同样,你可以从中传递任何你喜欢的对象/结构 “performsgue()”到“prepare(for:)”只需将发送方对象强制转换到 在确认“segue.identifier”后键入您传递的



  • 另一个选择是打电话

    "func performSegue(withIdentifier identifier: String, sender: Any?)"
    
    这将触发从ViewController到 SecondViewController。这是您希望在情节提要ie中保持在ViewController之间移动的代码,您控制从ViewController拖动到SecondViewController以创建一个segue,并为其提供唯一id

  • 每个UIViewController(的子类)都继承一个函数

    "func prepare(for segue: UIStoryboardSegue, sender: Any?)"
    
    系统将调用它,您可以在此处添加 如名称所示,实施前应准备好所需的一切 执行一个特定的序列。此时将执行下一个序列 ViewController已从情节提要加载到内存中(但是 尚未开始显示)。和的“segue”*参数
    “准备(对于segue:UIStoryboardSegue,发送方:Any?)”
    实际上有一个 属性“destination”,它实际上是下一个ViewController

    但要小心,因为您可能会有超过1段 ViewController到不同的下一个ViewController。
    因此
    “segue.destination”
    可能不是您想要的SecondViewController,如果 您有多个segue设置。因为系统调用
    “准备(对于segue:UIStoryboardSegue,发送方:Any?)”
    对于每个 继续离开此当前ViewController。请确保检查
    “segue.identifier”
    以确保后续代码正在处理 和你想象的一样

  • 现在你终于可以做你的标题问题了。 使用指向SecondViewController的指针,您可以自由设置任何 它拥有的财产,这是你的资本的特殊情况 对象。要完整循环,请使用
    “performsgue(带标识符:字符串,发件人:任何?)*
    “准备(用于segue:UIStoryb