5

Nella mia app ios swift ho un UITableViewController con celle aggiunte dinamicamente. Ogni cella ha un MKMapView incorporato e sto impostando il centro della mappa per ogni cella su coordinate diverse. Sto facendo così chiamando questo metodo:In ogni cella in UITableViewController ho una mappa incorporata. C'è un modo per cambiarlo con schermate di mappa?

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

all'interno 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 
} 

Questo va bene e funziona, ma immagino con un sacco di dischi ci saranno problemi con la memoria - anche ora con solo coppie di celle quando l'utente fa scorrere la tabella - ogni mappa viene caricata istantaneamente e posso solo immaginare quanta potenza di calcolo ci vuole per farlo.

Quindi la mia domanda è: esiste un modo per modificare la visualizzazione dinamica della mappa in una sorta di schermata della posizione effettiva della mappa? Funzionerà più velocemente quando si tratta di molte celle?

risposta

2

Sì, è possibile. Per fare ciò, dovresti passare ad usare UIImageView (chiamato mapImageView nel codice qui sotto) e MKMapSnapshotter. Per far volare davvero le cose, dovresti memorizzare nella cache le immagini prodotte da MKMapSnapshotter in modo che vengano caricate istantaneamente quando un utente torna a una cella vista prima. Questo approccio è delicato sulle risorse poiché utilizza solo l'unico MKMapSnapShotter globale anziché una mappa per ogni cella.

Ecco un codice che ho adattato alla situazione. Non ho incluso i dettagli su come memorizzare nella cache in modo specifico, poiché ciò dipende da come vuoi gestire la cache nella tua app. Ho usato il cocoapod Haneke: https://cocoapods.org/pods/Haneke in passato. Inoltre, ho impostato molte delle comuni opzioni di snapshot qui sotto, ma dovresti probabilmente adattarle al tuo caso d'uso.

//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 
        } 
       })