Removing First Annotation-MapView iOS - ios

I am working on mapview project. I have question related to removing annotation from the mapView.
I have implemented the following code but it removes annotation randomly, not the first one!
[mapView removeAnnotation:[self.mapView.annotations objectAtIndex:0]];

self.mapView.annotations gives you an NSArray of all the annotations, but it does not promise to be in the same order each time nor in the order you added annotations. You will have to find another way to get a reference to the one you intend to delete.

I have came across a solution. Whomever concerns about this question's answer, there you go
I have created an NSMUtable array and add all objects into array then remove first element from the mapview
[mapView removeAnnotation:[annotationArray objectAtIndex:0]];

Related

iOS Swift: how to check if Object exists in an Array so I don't add it to it, or re-create a GMSMarker with it?

I've been working with gmaps for iOS sdk and have this problem: each time the map pans or zooms and finishes(Im using the Delegate idleAtCameraPosition) in my serverside I compare the coordinates of the center of the map, in order to mark pins of places around it. I save the places in an array of "Places" objects, when they are close enough(1km) from the center coordinates.
My problem is that I haven't been able to avoid adding repeated objects to the array, so every time I do pan the map but don't change the camera position that much, the existing markers in the screen are re-added to the Places array. I tried using this code, but it doesn't work and the array can grow infinitely until crashing the app:
if(!arrayProp.contains(place)){
arrayProp.append(place)
}
but it doesn't work.
I also have another array of GMSMarkers that feeds itself from the Places array; tried this code to avoid re-creating markers in the map with Places objects that already existed:
for place in arrayProp {
let pinPlace = PlaceMarker(propied: place)//custom GMSMarker class
if(self.markerArray.contains(pinPlace) == false ) {
self.markerArray.append(pinPlace)
pinPlace.map = self.mapaGoogle
} else {
pinPlace.map = nil
}
}
Any help would be greatly appreciated; thank you
Probably your Place is using a default definition of Equatable which is not what you expect. You'll need something like this for contains() to work as expected:
struct Place: Equatable {
let there: Bool
}
func ==(lhs: Place, rhs: Place) -> Bool {
return lhs.there == rhs.there
}
Check Place's definition, or create one if it's using a default that checks only the necessary fields.
Have you tried using a Set? Swift supports a Set collection type that handles uniqueness for you. The type you store in the set just needs to implement Hashable, which you can implement on your GMSMarker class. (Or, if it's not your class, you can add an extension to implement the Hashable protocol)
See Apple's documentation on Sets.
If you're loading all of the new objects anyways, then you can just empty out the existing array before adding the new values. self.markerArray.removeAll() then add your new objects.

Mapbox selectAnnotation doesn't work in ViewDidLoad or first time in ViewDidAppear

I have a master-detail application, and my details page is a map. When I click on the element in the Master list, the map with whole bunch of markers shows up, zooms/pans into a specific location, and an annotation pops up describing what this location is.
The implementation is pretty simple, so I thought. In my viewDidAppear, I go through the list of annotations in my mapview and just call [mapView selectAnnotation: myAnnotation animated: FALSE] and it works fine. BUT NOT THE FIRST TIME!
I populate my map in ViewDidLoad, and the first time the ViewDidAppear is called, the mapView.annotations array is still empty. Is there a simple way to make it work even when I first enter the details view? Or do I have to create and populate the map in the AppDelegate?
Try using MGLMapViewDelegate and especially
func mapViewDidFinishLoadingMap(mapView: MGLMapView) {
// your code here
}
Maybe you can define a method at the DetailViewController,then when you trigger the method like tableview's didselect or prepareForSegue,you must get the DetailViewController's instance,finally,you can use this instance to call your user-defined method.

Updating annotation coordinates/location in Swift

I queried a set of coordinates for users around me from Parse(PFGeoPoint) and I have created annotations for said locations/coordinates. I will be updating the users location every 5 seconds and updating the location of the annotations, everything is working fine except for the fact that I'm having to remove and add annotations instead of them moving on their own similar to lyft, is there a way to do this in swift? please reply, thank you!!
Yes it is. As I can see from your tags, you are using MKPointAnnotation , so you an access its coordinate property and update it as you wish.
var coordinate: CLLocationCoordinate2D
So all you have to do is set it up like this:
annotation.coordinate = newCoordinate
For more information, please look at Accessing the Annotation’s Location.

How to delete the last annotation on a mapView

I have added a button on my .xib file with which I want to delete the last annotation that has been added.
So on the Touch-Down action I have implemented this:
-(IBAction)DeleteAnnotation:(id)sender {
[mapview removeAnnotation:[mapview.annotations lastObject]];
}
and I have even tried it this way:
-(IBAction)DeleteAnnotation:(id)sender {
[self.mapview removeAnnotation:self.mapview.annotations.lastObject]];
}
where mapview is my MKMapView Outlet.
The problem I encounter with both ways is that I have to press this specific button quite a few times before an annotation is removed.
Furthermore, the annotations remove themselves in a quite random way.
Is there something I am doing wrong or is it a software and simulator matter?
The annotations property of MKMapView is not guaranteed to return the annotations in the same order that you added them.
Making the assumption that the annotations array property will return the annotations in the same order that you added them is most likely the reason for the "strange" behavior you see. Please see these related answers for some more details:
MKMapView annotations changing/losing order?
How to reorder MKMapView annotations array
To get the behavior you want (which I assume is simply "remove the last annotation that was added explicitly by my code"), here are three possible approaches (there may be others):
Simplest approach is to keep a reference in a strong property to the last annotation you add (update the reference when you call addAnnotation). When you want to remove the "last annotation added", pass that saved reference to removeAnnotation. For example:
//in the interface...
#property (nonatomic, strong) id<MKAnnotation> lastAnnotationAdded;
//in the implementation...
//when you add an annotation:
[mapview addAnnotation:someAnnotation];
self.lastAnnotationAdded = someAnnotation; //save the reference
//when you want to remove the "last annotation added":
if (self.lastAnnotationAdded != nil)
{
[mapview removeAnnotation:self.lastAnnotationAdded];
self.lastAnnotationAdded = nil;
}
Another option is to loop through the map view's annotations array and search for the "last" annotation (or whatever attribute you're interested in). Once you have a reference to the "last" one (which may not necessarily be the last object in the array), you can call removeAnnotation on it. This approach assumes you have some property in the annotation objects themselves that let you identify an annotation as the "last" one. This may not always be possible.
Another option is to keep your own array of annotations and add annotation objects to this array whenever you call addAnnotation. This is similar to keeping the single reference to just the "last annotation added" except you keep track of the entire list in an order you can rely on. To remove the "last" one, you would get lastObject from your array instead of the map view's (assuming you keep the array in that order). You have to make sure to keep your array in sync as you add/remove annotations from the map.

MKPointAnnotation tag

Simple Question: Seems I cannot find the tag attribute for MKPointAnnotation class. It return error;
MKPointAnnotation *annotation = [[HCIAnnotationViewController alloc]
initwithHouse:house];
The following returns error (Property tag not found ob object of type "MKPointAnnotation"
NSLog(#"%d",annotation.tag);
My question is, if Im not allowed to set the tag, How am I supposed to detect which annotation was clicked.
The other approaches I followed are
Setting tag for MkAnnotationView, However in this what I found out is that the last annotation when added doesn't immediately call for viewForAnnotation (Might be because I'm adding around 1000 MkPointAnnotations to a small map, so it only calls when it comes to view.).
Please tell me how to resolve this?
Since MKPointAnnotation is not a subclass of UIView, has not a property called tag. Bu you have the property coordinate. I assume you have different coordinates for all of your annotations. So you can detect which one.
You just need to compare the coordinates.

Resources