Sending Images to Several Instances of a ViewContr

2019-09-18 14:12发布

问题:

I download several "events" from CloudKit in my program. Each one contains a picture, title, and location. The second two are used right away and there is no problem. The image is only seen if the user clicks on the info button on the annotation that shows the picture using a separate view controller. I am having trouble getting the images to be passed to the ViewController before it is used while also keeping each event's picture separate.

Here is where each record is queried from CloudKit and put into a for loop that send then to the method below:

func loadEvent(_ completion: @escaping (_ error:NSError?, _ records:[CKRecord]?) -> Void)
    {
        //...record is downloaded from cloudkit

                for record in records
                {
                    if let asset = record["Picture"] as? CKAsset,
                        let data = NSData(contentsOf: asset.fileURL),
                        let image1 = UIImage(data: data as Data)
                    {
                        self.drawEvents(record["LocationF"] as! CLLocation, title1: record["StringF"] as! String, pic1: image1)
                    }
                }
            }

Here is where the variables are assigned and used to create the point annotation (it is a custom one that includes an image):

func drawEvents(_ loc: CLLocation, title1: String, pic1: UIImage)
    {
        mapView.delegate = self
        let center = CLLocationCoordinate2D(latitude: loc.coordinate.latitude, longitude: loc.coordinate.longitude)
        let lat: CLLocationDegrees = center.latitude
        let long: CLLocationDegrees = center.longitude
        self.pointAnnotation1 = CustomPointAnnotation()
        self.pointAnnotation1.imageName = pic1
        self.pointAnnotation1.title = title1
        self.pointAnnotation1.subtitle = "Event"
        self.pointAnnotation1.coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long)
        self.pinAnnotationView = MKPinAnnotationView(annotation: self.pointAnnotation1, reuseIdentifier: nil)
        self.mapView.addAnnotation(self.pinAnnotationView.annotation!)
    }

Here is the function that makes EventPage appear when the info button on an MKMapAnnotation is clicked:

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

            let eventPageViewController:EventPageViewController = storyboard?.instantiateViewController(withIdentifier: "EventPage") as! EventPageViewController

            self.present(eventPageViewController, animated: true, completion: nil)
        }

Here is the ViewController for EventPage:

class EventPageViewController: UIViewController {

    @IBOutlet weak var eventPic: UIImageView!

    var photo: UIImage!

    override func viewDidLoad() {
        super.viewDidLoad()

        let firstViewController:FirstViewController = storyboard?.instantiateViewController(withIdentifier: "Home") as! FirstViewController

        photo = firstViewController.pointAnnotation1.imageName 
        //photo is nil

        eventPic.image = photo
   }
}

回答1:

Intead of storing your annotations in a single instance property (which means that you only have access to the last one), store them in an array, although you don't need to store them at all in order to respond to taps.

var annotations = [CustomPointAnnotation]()

func drawEvents(_ loc: CLLocation, title1: String, pic1: UIImage)
{
    mapView.delegate = self
    let center = CLLocationCoordinate2D(latitude: loc.coordinate.latitude, longitude: loc.coordinate.longitude)
    let lat: CLLocationDegrees = center.latitude
    let long: CLLocationDegrees = center.longitude
    var newAnnotation = CustomPointAnnotation()
    newAnnotation = CustomPointAnnotation()
    newAnnotation.imageName = pic1
    newAnnotation.title = title1
    newAnnotation.subtitle = "Event"
    newAnnotation.coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long)
    self.mapView.addAnnotation(newAnnotation)
    self.annotations.append(newAnnotation)
}

The annotation view that is tapped is passed to your delegate method, so you know which item it is. The annotation view's annotation property is your CustomPointAnnotation instance.

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

    let eventPageViewController:EventPageViewController = storyboard?.instantiateViewController(withIdentifier: "EventPage") as! EventPageViewController

    if let annotation = view.annotation as CustomPointAnnotation {
        eventPageViewController.photo = annotation.imageName
    }

    self.present(eventPageViewController, animated: true, completion: nil)
}