将数据从 plist 传递到 DetailView

Posted

技术标签:

【中文标题】将数据从 plist 传递到 DetailView【英文标题】:passing data from plist to DetailView 【发布时间】:2016-04-13 20:14:30 【问题描述】:

我正在从 Objective C 迁移到 Swift 并重写我的应用程序。目前遇到基本问题的问题,因此将不胜感激。

我已经设置了一个带有从 plist 数据中提取的注释的地图,效果很好。我还可以将标题和副标题传递给第二个视图控制器——没问题。

但是,我也想传递所选项目数据的所有其他字段,这就是我遇到的问题。

之前做得很好,但尽管进行了大量搜索,但找不到任何关于如何在 Swift 中执行此操作的指示。一个例子是完美的:-)

import MapKit

class Museums: NSObject, MKAnnotation 
    var title: String?
    var subtitle: String?
    var state: String?
    var latitude: Double
    var longitude:Double
    var coordinate: CLLocationCoordinate2D 
        return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    

    init(latitude: Double, longitude: Double) 
        self.latitude = latitude
        self.longitude = longitude
    







class ViewController: UIViewController, MKMapViewDelegate 
    @IBOutlet weak var mapView: MKMapView!

    var infoToPass: String?

    //View did load
    override func viewDidLoad() 
        super.viewDidLoad()
       mapView.delegate = self

        zoomToRegion()

        let annotations = getMapAnnotations()

        // Add mappoints to Map
        mapView.addAnnotations(annotations)

        mapView.delegate = self

        



    //Zoom to region

    func zoomToRegion() 

        let location = CLLocationCoordinate2D(latitude: 39.8, longitude: -98.6)

        let region = MKCoordinateRegionMakeWithDistance(location, 3150000.0, 3150000.0)

        mapView.setRegion(region, animated: true)
    

    // Annotations

    func getMapAnnotations() -> [Museums] 
        var annotations:Array = [Museums]()

        //load plist file           
        var myMuseums: NSArray?
        if let path =    NSBundle.mainBundle().pathForResource("MyAnnotationsUSA", ofType: "plist") 
            myMuseums = NSArray(contentsOfFile: path)
        
        if let items = myMuseums 
            for item in items 
                let lat = item.valueForKey("latitude") as! Double
                let long = item.valueForKey("longitude")as! Double
                let annotation = Museums(latitude: lat, longitude: long)
                annotation.title = item.valueForKey("title") as? String
                annotation.state = item.valueForKey("state") as? String
                annotations.append(annotation)
            
        

        return annotations
    


    func mapView(mapView: MKMapView, viewForAnnotation annotations: MKAnnotation) -> MKAnnotationView? 
        let reuseIdentifier = "pin"
        var pin = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseIdentifier) as? MKPinAnnotationView
        if pin == nil 
            pin = MKPinAnnotationView(annotation: annotations, reuseIdentifier: reuseIdentifier)
            //             pin!.pinColor = .Red
            pin!.canShowCallout = true
            pin!.rightCalloutAccessoryView = UIButton(type: .DetailDisclosure)
         else
        
            pin!.annotation = annotations
        
        return pin




func mapView(mapView: MKMapView, annotationView: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) 
    if control == annotationView.rightCalloutAccessoryView 

        self.performSegueWithIdentifier("showDetail", sender: self)
    



//prepare for segue

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 

        if self.mapView.selectedAnnotations.count == 0 
            //no annotation selected
            return;
        


        let  titleToPass = self.mapView.selectedAnnotations[0] //as? MKAnnotation

        print("\(infoToPass.title!)")

        let destination = segue.destinationViewController as! DetailViewController

        //This works
        destination.myLabelText = infoToPass.title!
        // This does not
        destination.myStateText = infoToPass.state

    

【问题讨论】:

只是对您的示例代码的风格评论:过多的空格和不一致的缩进有点伤害我的大脑:-) 杰尔。哎呀。对不起。希望你的大脑已经恢复 :-) 【参考方案1】:

在您的DetailViewController 中,您应该声明包含附加数据的属性。然后,在 prepareForSegue 方法中设置这些属性,就像设置 myLabelText 一样。除了两种语言之间的明显差异之外,这应该与在 Objective-C 中没有什么不同。

或者,如果有比这看起来更明显的内容,请在您的问题中添加更多信息。

更新:在查看您的 cmets 并在 Xcode 中重新创建您的示例之后,似乎由于您从地图视图中将选定的注释返回为 MKAnnotation,它显然不会有state 会员。尝试将其转换为 Museums,如下所示:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if self.mapView.selectedAnnotations.count == 0 
        //no annotation selected
        return
    

    let infoToPass = self.mapView.selectedAnnotations[0] as! Museums  // <-- NOTE
    let destination = segue.destinationViewController as! DetailViewController
    destination.myLabelText = infoToPass.title!
    destination.myStateText = infoToPass.state

【讨论】:

谢谢你。但是,我无法让它工作。我设置了一个字段以将其内容传递给 DetailViewController,其方式与我做 Title 的方式完全相同(在 plist 中称为 state 的字段)。但是,我收到错误消息“MKAnnotation 的值没有成员“状态”。使用 subTitle 或 Lat/Long 执行此操作没有问题,但我遇到问题的是 plist 中的其他字段。一如既往,非常感谢您的帮助/建议 经过深思熟虑,我为 NSObject、MKAnnotation 定义了一个类,并且我知道该类具有标题、副标题、纬度、经度和坐标的属性。所以这在传递标题等方面对我有用。但我的问题是访问 plist 中的部分,这些部分是 MKAnnotation 属性。对我称为“状态”的字段执行完全相同的操作会导致错误“MKAnnotation 类型的值没有成员“状态”” 勘误表:应该是“..评估 plist 中不是 MKAnnotation 属性的部分。 嗯,你是分别传递MKAnnotation实例和状态吗?您收到的错误消息让我认为您正在尝试从 MKAnnotation 实例中检索状态。您需要在详细视图控制器中使用两个成员变量(如果您有多个与 MKAnnotation 相关但与其成员无关的项目,则需要两个以上)。 嗨,杰尔。我更新了我的代码 sn-p 并添加了设置 MKAnnotation 信息的类。传递 MKAnnotation 属性的 Title、Subtitle、lat 和 long 没有问题。我想弄清楚的是如何从选定的注释中添加/提取其他信息。我收到“MKAnnotation 类型的值没有成员'状态”的错误。简而言之,我的问题是,一个人如何访问其他信息?

以上是关于将数据从 plist 传递到 DetailView的主要内容,如果未能解决你的问题,请参考以下文章

将数据从 TableView 发送到 DetailView Swift

如何将数据从基于 plist 的 UITableView 传递到 UIViewController

将数据从 TableView 传递到 ViewController

带有 .PLIST 的 Detailview 中的 UIPickerView

从 DetailView 将单元​​格添加到“收藏夹”TableView

如何将 DetailView 传递给 url 中的“slug”?