I have an app that calls addAnnotation exactly 3 times (after verifying that the coordinates are good using CLLocationCoordinate2DIsValid, passing a model that responds to id, title latitude, longitude and coordinate. In the model, I watch the callbacks by doing an NSLog in my coordinate method.
Note that coordinate and name are implemented as methods, although this should make no difference, right?
What I expect:
MapKit will access the coordinate method 3 times
What I get:
MapKit access the coordinate 3 times per coordinate, then tries a 4th time, even though there is no 4th coordinate and the app crashes on a memory exception as the result is nil.
I am pretty naive about MapKit, but there has to be some explanation for this that I'm missing.
Any help appreciated!
If the user location is shown on your map (the blue dot) you'll have four annotations, as the blue dot also is an annotation.
Your app probably crashes as the annotation used to show the user location has no method called coordinate
To prevent your code to call the method coordinate you can either check if the retrieved annotation is an instance of your custom annotation class:
if ([annotion isKindOfClass:[YourCustomeAnnotation class]])
// it's one of your annotations
else
// it's the current location annotation
or check if the current annotation is the current location anotation
if ([annotion isKindOfClass:[MKUserLocation class]])
// it's the current location annotation
else
// it's one of your annotations
Related
I'm struggling to identify how I can tell that the MKMapView is showing the current user location pin in a UI Test. This is a MKUserLocation annotation (and I've created an MKAnnotationView to use an image for the pin instead of the blue spot.)
Debugging tells me that the MKUserLocation annotation instance has a title of "My Location". I was expecting that the following would work:
app.maps.element.otherElements["My Location"]
would return it but [that code].exists returns false. Printing debugDescription of otherElements lists a whole set of annotations on the map but not the User Location.
Is there a different type of XCUIElement that represents the pin/annotation/annotation view that I can check for?
Use accessibility labels to access your MKAnnotationView. In your code, retrieve your user location annotation and set an accessibility label for it:
yourAnnotation.accessibilityLabel = "labelYouWillUseToFindIt"
Then during your tests you can do:
app.maps.element.otherElements["labelYouWillUseToFindIt"]
Use print(app.debugDescription) to see if your annotation is visible and if not, force it to be accessible with:
yourAnnotation.isAccessibilityElement = true
You can read more about accessibility labels here
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];
I'd like to make an editable callout, and from a quick look it seems like the best way is to create a textfield over it in the view.
So, I was wondering how to get the CGPoint of an annotation so that I can use it in placing my CGRect of a textfield. This is the code I'm using to display an annotation at a tapped point, how would one do the reverse?
If anyone suggests better ways to create an editable callout, I'm welcome to suggestions
var point:CGPoint = gestureRecognizer.locationInView(self.Map)
EventLoc = self.Map.convertPoint(point, toCoordinateFromView: self.Map)
I'm not too familiar with Swift yet, but independent from the language, MKMapView has a method convertCoordinate:toPointToView: which you can use to convert a CLLocationCoordinate2D to a CGPoint.
EDIT
From the MKMapView reference:
Converts a map coordinate to a point in the specified view.
So in your case the last argument should be your map view:
The view in whose coordinate system you want to locate the specified map coordinate. If this parameter is nil, the returned point is specified in the window’s coordinate system. If view is not nil, it must belong to the same window as the map view.
I'm working on an app that shows a couple of places on the map along with the user's current position.
I have two small problems with it:
First off, I want the current location pin to be the default blue circle, but it shows a green pin just like the other locations.
Second problem, whenever I touch the screen, the current location pin drops again. It just can't seem to be steady like the other ones. It's like it's being called whenever I interact with the app.
Make sure you set your mapView delegate to self...that should fix the pin color. Not sure about your other problem
// in the viewDidLoad
[mapView setDelegate:self];
where "mapView" is defined as "IBOutlet MKMapView *mapView;"
I am working on an application which use user location updates, I have got the current latitude and longitude and display the current location of the user and annotate the pin, However I need help regarding moving a pin when user changes his location or when user moves and get new latitude and longitude the pin should also move to that position.
To show the current location, you could just set showsUserLocation to YES and let the map show the blue dot for you.
If you want to show your own annotation instead and have it move automatically, implement setCoordinate: in the class that implements the MKAnnotation protocol.
Then when the coordinates change, update the annotation's coordinate and the map view will automatically (via KVO) move the annotation's view/pin.
You could also remove the annotation and create a new one at the new location but that can result in flicker.
If you are using Core Location to get location updates, you would update the annotation's coordinates in the locationManager:didUpdateToLocation:fromLocation: delegate method.