iOS: Best way to get position user - ios

I have a MKMapView class, and I want to show on the map the user position represented by a image.
So, I read this tutorial: http://www.switchonthecode.com/tutorials/getting-your-location-in-an-iphone-application
This guy use the locationmanager on the view, I need to use it on a MKMapView.
For me, the best way to do this is creating a class just for control the user position?
How can I do this?
Thanks!!

First you want the location to show up on your map:
yourMapView.showsUserLocation = YES;
Then you need to handle the delegate method for displaying an annotationview for the user location:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id < MKAnnotation >)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
// Create a custom MKAnnotationView here that will display your image.
}
}
Make sure you set the delegate on your MKMapView properly.

For this you need to implement the MKAnnotation & MKMapView Delegates.
Implement this method for changing the default pin to the custom image.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
// Create a custom MKAnnotationView here that will display your image.
//user current location
}
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[MyLocation class]])
{
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
}
else
{
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.image=[UIImage imageNamed:#"yourImage.png"];
return annotationView;
}
return nil;
}
Please refer this tutorial.

Related

Remove The Information Button Option From Map Annotation Title

PREAMBLE
I have implemented a map annotation using MKMapView and MapAnnotation. When tapped a title view appears as depicted in the following image.
I have used the following LOC to implement said map annotation:
// VENUE 1 PIN.
CLLocationCoordinate2D venue1Location = CLLocationCoordinate2DMake(-27.5, 153.5);
MapAnnotation *venue1Pin = [[MapAnnotation alloc] initWithTitle:#"1 ONE ST" Location:venue1Location];
VIEW FOR ANNOTATION DELEGATE METHOD:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MapAnnotation class]])
{
MapAnnotation *venueLocationAnnotation = (MapAnnotation *)annotation;
MKAnnotationView *venueLocationAnnotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:#"customAnnotation"];
venueLocationAnnotationView.rightCalloutAccessoryView.hidden = YES;
if (venueLocationAnnotationView == nil)
venueLocationAnnotationView = venueLocationAnnotation.annotationView;
else
venueLocationAnnotationView.annotation = annotation;
return venueLocationAnnotationView;
}
else
{
return nil;
}
}
QUESTION
How do I remove the information button from the aforementioned map annotation title view ?
You can use following statement:
You have to implement following delegate method for this:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
...
venue1Pin.rightCalloutAccessoryView = nil;
...
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView.hidden=YES;
return annotationView;
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKPointAnnotation class]])
{
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"yourPinIdentifier"];
if (!pinView)
{
pinView.rightCalloutAccessoryView.hidden=YES;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
}
return pinView;
}
}

Single Click on Apple map leads crashed in my iOS application. What is the possible reason behind it?

Here is only one delegate for it.
#pragma mark - Map Delegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *reuseId = #"annotation";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView
dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (annotationView == nil)
{
annotationView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation
reuseIdentifier:reuseId];
}
else
{
//Update view's annotation reference
//because we are re-using view that may have
//been previously used for another annotation...
annotationView.annotation = annotation;
}
annotationView.image = [UIImage imageNamed:#"spotcrewcellicon_image.png"];
return annotationView;
}
#end
You are probably trying to perform operations on the annotation for the user's location, a common cause of crashes in viewForAnnotation:
if([annotation isKindOfClass:[MKUserLocation class]])
{
return nil; // Use default system user-location view.
}
should solve your problem.

Avoid to display callout when a MKAnnotation is tapped

I want to avoid to display a callout when I tap a MKAnnotation, just to display the pin, and when I tap, I want nothing happens.
Thanks
Try like this .
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"sample"];
annView.canShowCallout = NO;
return annView;
}
Hope this code is useful for you.
This will help you.
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *reuseId = #"pin";
MKPinAnnotationView *pinV = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (pinV == nil)
{
pinV = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
pinV.canShowCallout = NO; // You have to add this.
}
return pinV;
}

Check if Annotation callout is clicked

I want to check if the annotation is clicked:
So it goes from this:
To :
Here's my code that shows the annotation:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[MyLocation class]]) {
MKAnnotationView *annotationView = (MKAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.image = [UIImage imageNamed:#"arrest.png"];//here we use a nice image instead of the default pins
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
} else {
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
the rightCalloutAccesoryView is a blue button inside the callout. But i need to hide something when the user clicks on the annotation.
Does anyone know how to check this/do this?
Thanks is advance
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
//do your code
}

How do I put a right accessory button onto the current location callout?

I want to add a right accessory button to the current user location callout. I've found a few questions on the topic but they don't seem to work for me. Here is the code I have so far, I have successfully put the right accessory button onto my other annotations:
- (MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
//TODO: this doesn't seem to be working?
if ([annotation isKindOfClass:[MKUserLocation class]]) {
MKAnnotationView * aV = [mapView viewForAnnotation:annotation];
aV.canShowCallout = YES;
aV.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return nil;
}
return nil;
}
I've read in a few places that the solution is to make a custom MKAnnotationView for the User Location but I haven't seen a demonstration of how this is done for the user location -- I have successfully done this for the other annotations on my map.
Sample code would be the most helpful, thanks!
Again you should get reference of user location annotation view.
Following methods gets called in iOS >= 5
Option 1
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
MKAnnotationView *aV;
for (aV in views) {
if ([aV.annotation isKindOfClass:[MKUserLocation class]]) {
MKAnnotationView* annotationView = aV;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
}
}
See the delegate method below as well
Alternative Method
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKAnnotationView* annotationView = [mapView viewForAnnotation:userLocation];
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
Make sure to add the delegate method so you can do whatever when the callout button is tapped:
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
In any iOS either of these method gets called and you can add right/left accessorybutton to it. ensure that you do not add this button twice by checking subview count of user location annotation view.
You can also add/remove accessoryviews it in runtime, but I believe you will not want to remove it.buttons
Your main problem is that you are returning nil in both cases. You should also use a reuse identifier.
- (MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]]) {
MKAnnotationView * aV = [mapView dequeueReusableAnnotationViewWithIdentifier:#"locationView"];
if (aV == nil)
aV = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"locationView"];
aV.canShowCallout = YES;
aV.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return aV;
}
return nil;
}
You will also need to implement:
- (void)mapView:(MKMapView *)_mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
for the behavior of the callout accessory.

Resources