I have an IOs app that adds annotations when they enter the visible map view. This works well and keeps the total pins on the map low however this also looks buggy as the annotations are only added to the map when map scrolling has finished/completed. Does anyone know a way to add pins to the map whilst it's still scrolling so that the experience is fluid?
Many thanks,
Matt
Do you add annotaion to MapView on the main thread?
ex)
dispatch_async(dispatch_get_main_queue(), {
self?.mapView.addAnnotation(venueAnnotation)
})
Related
I have just build an swift app that takes data+coords from dynamoDB and puts it onto the ios mapkit. There are two sets of coords: one for current user location and one from dynamoDB. I want these coords to be able to update inside the map, but do not want the actual mapView to zoom and move at all (only the user can zoom and move).
I have achieved everything above except the last part. Currently whenever the annotations are added and mapView.showAnnotations is called, the mapView zooms and moves to enclose the annotations. How do I disable this?
To show mapView annotations without updating mapView zoom and constraints, use addAnnotations() rather than showAnnotations.
I am guessing that you used code from online (which we all do, no worries) and that your code looked something like this. If I am right, then you likely have a line somewhere like this:
[map setRegion:scaledRegion animated:YES];
That line is the issue. You need to use some sort of boolean to make it so that it only happens once. So you could set the boolean has_mapped = false until you have called your update method once, at which point it = true. Then change your line to say something like,
if (has_mapped)
[map setRegion:scaledRegion animated:YES];
How does one get a list (array) of currently visible overlay from a MapkitView?
Background - for example I want to show direction arrows to the center of certain Overlay types on my mapkitview, however how do I get the visible ones? There seems to be no way to do this I can see? So do I need to got through all overlays (actually ~8000) and do my own check to see what would be showing on the screen? Seems a waste if MapKit would have already effectively done this as part of deciding what overlays need to be displayed at a given time.
I've been tinkering with some similar problems and the most efficient way I could figure out was to add the overlays as annotations as well, since MKOverlay implements MKAnnotation. Then you would be able to use annotationsInMapRect for the currently displayed mapRect. However this would also return any regular MKAnnotations, and only uses the calculated middle of the overlay. The only way (so far as I figured) to only get the overlays would be to iterate over each overlay and use:
-(BOOL)intersectsMapRect:(MKMapRect)mapRect;
on the currently visible mapRect.
If you found another way I'd be happy to hear!
I made a settings tab for the MapView's ViewController and it works fine when I open the MapViews's VC the first time. but when I change the settings after I opened and loaded the mapView the first time the settings that I changed don't apply to the mapView because it did not refresh. Is there a way of refreshing the data of the mapView? I have searched everywhere and couldn't find an answer.
if this question have been answerd before can you link me to it? Thank you.
I'm using the GoogleMaps ios sdk.
and I'm using obj-c.
If your settings just changes the icons, annotations, map markers or layers color , or location of markers or layer, the simplest way to do is clear all the markers and layers you add on the map view and re-add them. For example, implement a refreshMapView method
-(void)refreshMapView
{
[mapView clear];//this line clears all the markers or layers you drew on the mapView.
// then implement your method to re-draw the markers and layers, or load new settings.
// for example, go through your marker list, and add them as follows:
for (id yourobject in yourMarkerArray){
GMSMarker *marker = [GMSMarker markerWithPosition:coordinatesOfMarker];
//custom marker here, set title, or snippets, or icon, etc...
marker.map = mapView;
}
// you can also redraw any map overlay here...
}
Jing's answer to implement a refreshMapView method is good, you could call that in your map view controller's viewWillAppear section.
Make sure you're actually setting the mapView properties in the same scope — i.e., your settings view and your map view may be looking at a different object or changes may be getting discarded. Without seeing the code for how you're trying to modify those settings, it's difficult to say.
I've got a performance problem regarding adding annotations to maps in iOS (using the standard mapkit methods - hence using Apple maps). I'm trying to add a large number of annotations (10000+) in bulk, using the (void)addAnnotations:(NSArray *)annotations method. The annotation objects are nothing special - a very basic class that implements MKAnnotation with only the constructor defined as follows:
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d {
if(self = [super init]) {
title = ttl;
coordinate = c2d;
}
return self;
}
In order to test, I've created a basic app that simply adds the annotations to a basic map view on load, and it takes around 6-7 seconds on an iPad 2. Very acceptable performance. However, things get complicated when I embed the same basic map view in my own application. It's the exact same logic, but when I do it in my app, it takes around 50 seconds to load all the annotations.
My app has a bunch of views within each other. To pinpoint the problem, I've started embedding the map view starting from the lowest level, until I reach the top level. I've done profiling in each step to see if it helps the performance, but I don't see any results - it's still around 50 seconds. Right now, my app basically just loads and adds the annotations to the top and only level map view, ideally the same as the standalone app, but for whatever reason, I still see the annotation rendering taking around 50 seconds. The only reasonable explanation I have is in regards to some of the app settings I have that somehow interferes with the map performance. I've done a bunch of reading to come up with a solution to no avail.
Anyone have any ideas about what might be the problem here? Thanks!
There is no actual "problem". I mean, you have more than 10000 allocations, draws and renderings that are actually having impact on the performance of the application.
My suggestion is to intercept the user navigation on the map. Use something like [mapView visibleMapRect] to get the visible portion of the map on the screen. Get the coordinates of the rect (maybe a little bit bigger so that cannot be noticed by the user when moving the map) and load only the annotations within that rect.
As the user moves, you only have to load the annotations that are within the new rect MINUS the annotations that were already loaded in the previous rect. I guess you can also remove the annotation when they go out of the screen.
This resembles a little bit what Apple suggests to do when dealing with scrolling views. I remember the application in which the user would have to load the content of the previous and next section of the scrollview (and to release the content of the previous-1 view) so to have a slow memory consumption and still maintaining a good user experience.
Try to think about what the user is looking at, try to show only the annotations that matter that portion (or region as they are called in the MKMapView jargon) and I think your app responsiveness will just improve right away.
I am trying to make a snapshot from a view with a MKMapview to provide a springboard like folder animation when the user selects an annotation.
The official way to make a snapshot of the current window is presented here. This works fine (though quite slow) unless the mapview is not zoomed in too much and has a "regionThatFits" set. The map & the marker make an unmatched "jump" to the left and the gridlines of the mapview are visible:
Before screenshot:
After screenshot:
I suppose it has something to do with the tiled parts of the map but I don't know how to prevent that behaviour.
Any thoughts?