【问题标题】:How to pass firebase data information to another viewcontroller when mapview annotation is clicked?单击mapview注释时如何将firebase数据信息传递给另一个viewcontroller?
【发布时间】:2020-05-15 15:23:21
【问题描述】:

我知道类似的问题已经被问过很多次了。只是找不到适合我需要的解决方案。请帮忙

我一直在尝试将信息从 firebase 加载到 mapview。我能够附加所有信息视图地图注释视图。但是我想要做的是在单击地图注释视图时将 Firebase 数据传递给新的视图控制器。单击注释时,我可以进入另一个视图控制器,但加载了错误的 firebase 数据

到目前为止我尝试过的代码:

   override func viewDidLoad() {
    super.viewDidLoad()

    self.mapView.delegate = self
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    locationManager.requestLocation()

  observeGeofire()
}

func observeGeofire() {
  let dataRef = Database.database().reference().child("Shoutout")

            dataRef.observeSingleEvent(of: .value, with: { (snapshot) in



                for snap in snapshot.children {
                    let postSnap = snap as! DataSnapshot

                    if let dict = postSnap.value as? [String: AnyObject] {
                let Lat = dict["lat"] as! CLLocationDegrees
                    let Long = dict["long"] as! CLLocationDegrees
                        let EVENT = dict["Event Type"] as? String
                        let Radmap = self.Rad
               var annotations = MKPointAnnotation()
                     annotations.coordinate = CLLocationCoordinate2D(latitude: Lat, longitude: Long)
                       annotations.title = dict["title"] as? String
                        let loc = CLLocation(latitude: Lat, longitude: Long)
                             let distanceFromUser = (self.Location.distance(from: loc))/1000
                let span = MKCoordinateSpanMake(0.25, 0.25)

                        if distanceFromUser < Radmap && EVENT! == self.sovcCET {
                            self.mapView.addAnnotation(annotations)
                            print("testing text for \(self.sovcCET)")

                        } else if distanceFromUser < Radmap && self.sovcCET == "All Events"{
                           self.mapView.addAnnotation(annotations)
                        } else if distanceFromUser < Radmap && self.sovcCET == "Choose Event" {
                             self.mapView.addAnnotation(annotations)
                        } else {
                            print("failed test")
                        }
                }

                }

            })
}

 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?{
    if annotation is MKUserLocation {
        //return nil so map view draws "blue dot" for standard user location
        return nil
    }
    let reuseId = "pin"
    var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
    pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
    pinView?.pinTintColor = UIColor.red
    pinView?.canShowCallout = true
    let smallSquare = CGSize(width: 30, height: 30)
    let button = UIButton(frame: CGRect(origin: CGPoint(x: 0,y :0), size: smallSquare))
    let rightButton = UIButton(type: .contactAdd)
    rightButton.tag = annotation.hash

    pinView?.animatesDrop = true
    pinView?.canShowCallout = true
    pinView?.rightCalloutAccessoryView = rightButton
    pinView?.leftCalloutAccessoryView = button

    return pinView
}

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView,
             calloutAccessoryControlTapped control: UIControl) {

    //mapToDetails
    if control == view.rightCalloutAccessoryView {
    performSegue(withIdentifier: "mapToDetails", sender: self)
    }

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "mapToDetails" {
        if let destination = segue.destination as? shoutoutDetailViewController {

            destination.shoutoutSelected = ShoutoutSelected
    }
    }
}

ShoutoutSelected 实际上是一个包含多个变量的类 Shoutout 的实例化,如下所示:

class Shoutout: NSObject {
// CLLocationDegrees
var event: String?
var when: String?
var Place: String?
var details: String?
var timestamp: NSNumber?
var whenTimeStamp: NSNumber?
var picsImageUrl: String?
var fromId: String?
var lat: CLLocationDegrees?
var long: CLLocationDegrees?
var title: String?
var subtitle: String?
var shoutoutId: String?
var distance: Double?
var tit: String?
var capt: String?



init(dictionary: [String: Any]) {
 self.event = dictionary["Event Type"] as? String
self.when = dictionary["Date and Time"] as? String
 self.whenTimeStamp = dictionary["Date and Time"] as? NSNumber
 self.Place = dictionary["place"] as? String
 self.details = dictionary["details"] as? String
 self.timestamp = dictionary["TIMESTAMP"] as? NSNumber
 self.picsImageUrl = dictionary["postPicUrl"] as? String
 self.fromId = dictionary["FROM"] as? String
 self.lat = dictionary["lat"] as? CLLocationDegrees
 self.long = dictionary["long"] as? CLLocationDegrees
 self.title = dictionary["title"] as? String
 self.subtitle = dictionary["subtitle"] as? String
 self.shoutoutId = dictionary ["ResponseID"] as? String
    self.tit = dictionary ["Event Title"] as? String
    self.capt = dictionary ["Captions"] as? String
}

func shouterPartnerId() -> String? {
    return fromId
}

func soid() -> String? {
    return shoutoutId
}

}

再次感谢

【问题讨论】:

    标签: swift firebase firebase-realtime-database mkmapview


    【解决方案1】:

    你可以使用下面的代码来代替prepare segue

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView,
             calloutAccessoryControlTapped control: UIControl) {
    
        let vc = self.storyboard?.instantiateViewController(withIdentifier: 
        "DestinationViewController") as! DestinationViewController
        vc.shoutoutSelected = ShoutoutSelected
        self.navigationController?.pushViewController(vc, animated: true)
    }
    

    【讨论】:

    • 感谢您的回复。现在,当我单击每个 mapview 注释时,我可以转到destinationviewcontroller。但是,当它连接到目标视图控制器时,即使它是从不同的注释分隔的,相同的 Firebase 数据也会填充它。
    【解决方案2】:

    使用 performSegue 时,performSegue(withIdentifier: "mapToDetails", sender: self) 您可以在 sender 中发送您的对象。所以不要发送sender : self 试试sender: ShoutoutSelected

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView,
                 calloutAccessoryControlTapped control: UIControl) {
    
        //mapToDetails
        if control == view.rightCalloutAccessoryView {
        performSegue(withIdentifier: "mapToDetails", sender: ShoutOutSelected) 
        }
    
    }
    

    现在在prepareForSegue, 中,您可以检索sender 的值并将其传递给目标控制器。

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
        if segue.identifier == "mapToDetails" {
            if let destination = segue.destination as? shoutoutDetailViewController {
    
                destination.shoutoutSelected = sender as! Int // here sender = ShoutoutSelected, downcast it from Any to your desired type. I am considering destination.shoutoutSelected is of Int type.
            }
        }
    }
    

    【讨论】:

    • 科舒您好,感谢您的回答。我的 ShoutoutSelected 实际上是一个名为 Shoutout 的单独类的实例化,具有不同的变量。我在我的问题中添加了它。我将如何从发件人那里贬低它?再次感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    • 2018-09-26
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多