5

In meiner ios swift App habe ich eine UITableViewController mit Zellen dynamisch hinzugefügt. Jede Zelle hat eine MKMapView eingebettet und ich setze das Zentrum der Karte für jede Zelle auf verschiedenen Koordinaten. Ich mache so durch diese Methode aufrufen:In jeder Zelle in UITableViewController habe ich eine Karte eingebettet. Gibt es eine Möglichkeit, es stattdessen zu Screenshots der Karte zu ändern?

func centerMapOnLocation(location: CLLocation, map: MKMapView, radius: CLLocationDistance) { 
    let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, 
     radius * 2.0, radius * 2.0) 
    map.setRegion(coordinateRegion, animated: true) 
} 

innen cellForRowAtIndexPath:

override func tableView(tview: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tview.dequeueReusableCellWithIdentifier("cell") as! SingleCall 
    let user:SingleUser = self.items[indexPath.row] as! SingleUser 

    let regionRadius: CLLocationDistance = 150 
    let initialLocation = CLLocation(latitude: user.coordinate.latitude, longitude: user.coordinate.longitude) 

    centerMapOnLocation(initialLocation, map: cell.eventMap, radius: regionRadius) 

    cell.eventMap.zoomEnabled = false 
    cell.eventMap.scrollEnabled = false 
    cell.eventMap.userInteractionEnabled = false 
} 

Das ist in Ordnung und es funktioniert, aber ich mit vielen Aufzeichnungen vorstellen, wird es Probleme mit dem Gedächtnis - auch jetzt mit nur paar Zellen, wenn der Benutzer die Tabelle scrollt - jede Karte lädt sofort und ich kann mir nur vorstellen, wie viel Rechenleistung dafür benötigt wird.

Also meine Frage ist - gibt es eine Möglichkeit, die dynamische Kartenansicht zu einer Art von vielleicht Screenshot der tatsächlichen Position der Karte zu ändern? Wird es schneller arbeiten, wenn es um viele Zellen geht?

Antwort

2

Ja, es ist möglich. Um dies zu tun, sollten Sie einen UIImageView (im folgenden Code mapImageView genannt) und MKMapSnapshotter verwenden. Um die Dinge wirklich fliegen zu lassen, sollten Sie die Bilder, die MKMapSnapshotter erzeugt, zwischenspeichern, damit sie sofort geladen werden, wenn ein Benutzer zu einer Zelle zurückscrollt, die zuvor gesehen wurde. Dieser Ansatz ist ressourcenschonend, da er nur den einen globalen MKMapSnapShotter und nicht eine Zuordnung für jede Zelle verwendet.

Hier ist ein Code, den ich an Ihre Situation angepasst habe. Ich habe die Details zur Cache-Speicherung nicht im Detail erwähnt, da dies davon abhängt, wie Sie mit dem Caching in Ihrer App umgehen möchten. Ich habe die Haneke Cocoapod verwendet: https://cocoapods.org/pods/Haneke in der Vergangenheit. Außerdem habe ich viele der üblichen Snapshot-Optionen unten festgelegt, aber Sie sollten sie wahrscheinlich an Ihren Anwendungsfall anpassen.

//CHECK FOR CACHED MAP, IF NOT THEN GENERATE A NEW MAP SNAPSHOT  
let coord = CLLocationCoordinate2D(latitude: placeLatitude, longitude: placeLongitude) 
       let snapshotterOptions = MKMapSnapshotOptions() 
       snapshotterOptions.scale = UIScreen.mainScreen().scale 
       let squareDimension = cell.bounds.width < cell.bounds.height ? (cell.bounds.width)! : (cell.bounds.height)! 
       snapshotterOptions.size = CGSize(width: squareDimension, height: squareDimension) 
       snapshotterOptions.mapType = MKMapType.Hybrid 
       snapshotterOptions.showsBuildings = true 
       snapshotterOptions.showsPointsOfInterest = true 
       snapshotterOptions.region = MKCoordinateRegionMakeWithDistance(coord, 5000, 5000) 

let snapper = MKMapSnapshotter(options: snapshotterOptions) 

       snapper.startWithCompletionHandler({ (snap, error) in 
        if(error != nil) { 
         print("error: " + error!.localizedDescription) 
         return 
        } 
        dispatch_async(dispatch_get_main_queue()) { 
         guard let snap = snap where error == nil else { return } 

         if let indexPaths = self.tview.indexPathsForVisibleRows { 
          if indexPaths.contains(indexPath) { 
           cell.mapImageView.image = snap 
          } 
         } 
         //SET CACHE HERE 
        } 
       })