In my app i am showing some place on map view using MKMapView . It was showing map fine. But from yesterday it is showing only grid and not showing the map , when i add delegate method it goes in the mapviewdidfiailtoload sometime.
I am using the below code
//mapview
myMapView=[[MKMapView alloc] initWithFrame:CGRectMake(0,gameNameLabel.frame.size.height, 320, 181)];
myMapView.mapType=MKMapTypeStandard;
myMapView.delegate=self;
LocationModel *loc=presentGame.location;
NSArray *cordinates=[loc.geoCordinates componentsSeparatedByString:#","];
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = [[cordinates objectAtIndex:0] doubleValue];
zoomLocation.longitude= [[cordinates objectAtIndex:1] doubleValue];
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
// 3
MKCoordinateRegion adjustedRegion = [myMapView regionThatFits:viewRegion];
// 4
[myMapView setRegion:adjustedRegion animated:YES]; [scroll addSubview:myMapView];
Place *pin = [[Place alloc] init];
pin.name = loc.gameLocation;
pin.latitude = [[cordinates objectAtIndex:0] doubleValue];
pin.longitude = [[cordinates objectAtIndex:1] doubleValue];
PlaceMark* Place1 = [[PlaceMark alloc] initWithPlace:pin];
Place1.tagg=1;
[myMapView addAnnotation:Place1];
//end of mapview
- (MKAnnotationView *)mapView:(MKMapView *)mapView1 viewForAnnotation:(id )annotation {
static NSString *identifier = #"PlaceMark";
if ([annotation isKindOfClass:[PlaceMark class]]) {
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [mapView1 dequeueReusableAnnotationViewWithIdentifier:identifier];
annotationView.tag=[mapView1.annotations count];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
return annotationView;
}
return nil;
}
METERS_PER_MILE is defined as 1609.344
and i have set delegate in .h file .
All thing was working fine but now it showing the grid only , it showing Pin atleaset
I had the same problem MKMap View showing Only Grid not Showing Map View. I found out it was related to a change I made to the time/date on my mac. When I fixed the time and date to current time, the map worked again.
The iOS simulator comes with the official maps app included. Open that and verify that it can get tiles, it could be a network issue. If the Maps app isn't showing any tiles then you have network issues.
Can you try by turning off the animation by changing the line
[myMapView setRegion:adjustedRegion animated:YES];
By
[myMapView setRegion:adjustedRegion animated:NO];
Related
I am trying to add annotations on MKMapView. The annotations can show up when the coordinates are not (0, 0), but when I set the annotation's coordinate as (0, 0), the annotation view can NOT show up.
On the iPhone XS simulator and device, only one annotation showing(location (10, 0)), the location(0, 0) not show up.
It seem that the (0, 0) annotation is add at the bottom of the map, not at the west side of Africa.
Any suggestion is appreciated.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Add Annotation
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake(0, 0);
[self.mapView addAnnotation:annotation];
MKPointAnnotation *annotationZero = [[MKPointAnnotation alloc] init];
annotationZero.coordinate = CLLocationCoordinate2DMake(10, 0);
[self.mapView addAnnotation:annotationZero];
}
#pragma mark - MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
static NSString *reuseIdentifier = #"map_annotation";
MKAnnotationView *annotationView = [_mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier];
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
}
annotationView.image = [UIImage imageNamed:#"annotation_icon"];
return annotationView;
}
return nil;
}
I started with a test using Swift and CLLocationCoordinate2DMake(0,0) worked fine, so the problem isn't related to a device but it is language specific issue.
You cannot use (0,0) in objective-c, instead use DBL_MIN, which is the smallest number possible, like so:
CLLocationCoordinate2DMake(DBL_MIN, DBL_MIN)
I've been searching for hours now to find a good tutorial on how to add annotations given a class that holds locations and images of an object (in my case, object is called as EVENT).
Check out what I've done so far, I'm calling this method setupAnnotations from viewDidLoad.
- (void)setupAnnotations {
_allEvents = [EventEntity MR_findAll];
for (EventEntity *event in _allEvents) {
AVEventAnnotationView *annotation = [[AVEventAnnotationView alloc] initWithOperator:event];
CLLocation *eventLocation = [[CLLocation alloc] initWithLatitude:[[event latitude] doubleValue] longitude:[[event longitude] doubleValue]];
annotation.coordinate = eventLocation.coordinate;
MKPlacemark *eventPlacemark = [[MKPlacemark alloc] initWithCoordinate:eventLocation.coordinate addressDictionary:nil];
MKMapItem *eventItem = [[MKMapItem alloc] initWithPlacemark:eventPlacemark];
// Im loading image from URL for or based on event object
UIImageView *imageContainer = [[UIImageView alloc] init];
[imageContainer sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#%#",fullBannerImgPath,[event bannerImg]]]];
[_bannerImagesArray addObject:imageContainer];
BOOL hasAnnotation = NO;
for (AVEventAnnotationView *ann in self.mapView.annotations) {
if([ann isKindOfClass:[AVEventAnnotationView class]])
{
if([[annotation.eventEntity dataId] isEqualToString:[ann.eventEntity dataId]])
{
hasAnnotation = YES;
break;
}
}
}
if(!hasAnnotation)
[self.mapView addAnnotation:annotation];
}
}
And here's my mapview delegate:
- (MKAnnotationView *)mapView:(MKMapView *)mapViewIn viewForAnnotation:(id <MKAnnotation>)annotation {
if (mapViewIn != self.mapView || [annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
static NSString *annotationIdentifier = #"SPGooglePlacesAutocompleteAnnotation";
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
// STUCK HERE
annotationView.image = [UIImage imageNamed:#"LocationBlue"];
annotationView.frame = CGRectMake(0, 0, 80, 80);
annotationView.draggable = NO;
annotationView.canShowCallout = YES;
return annotationView;
}
I'm new to implementing MKMapView. I just read awhile ago the difference between annotation and annotation view.
Anyway, back to my main question or my main problem: How to put annotation/annotationview to mkmapview given I have an array of EVENTS with latitude, longitude and Images?
I don't know what is AVAnnotationView but I would say you don't need it. You just have to make your Event class conform to MKAnnotation protocol, that is add the property coordinate of type CLLocationCoordinate2D to the Event class. After this just add the events to the map with addAnnotations.
In your mapView:viewForAnnotation: you determine what is the annotation that is being displayed (what is the event that is being displayed) and so you get the image you want to display (you may use tags or any other mean) and set the image for annotation view.
Or you just say something like:
if event = annotation as? AVEventAnnotationView {
//add your image and do stuff
}
I am trying to use some delegate methods in MKMapViewDelegate. Specifically, I want to give the pop out an accessory arrow so that when user touches it, it launches native map application (for full blown mapping functions.)
I think I understand correctly that once the VC is set up as a delegate of itself then the protocol methods get called automatically. In that case do delegate methods get called automatically or do you have to do something else?
Here is method to launch map.
-(void) geoCodeAndMapIt {
NSString* location = #"156 University Ave, Palo Alto, CA 94301";
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:location
completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc]
initWithPlacemark:topResult];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(placemark.coordinate, 5000, 5000);//5000 is meters
region.span.longitudeDelta /= 8.0;
region.span.latitudeDelta /= 8.0;
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotation:placemark];
}
Here is method that should add accessory arrow to callout but is not firing:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"loc"];
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return annotationView;
}
How do I get this method to fire so I get accessory arrow? Thanks for any suggestions.
Why don't you use this method when you click the button in you annotation view this method is fired and you can perform your custom action there.
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
//Do whatever you want to do here.
PropertyLocation *location = (PropertyLocation*)view.annotation;
for(PropertyDTO *property in self.items)
{
if(property.location == location)
{
PropertyDetailVC *detailVC = [PropertyDetailVC propertyDetailVCWithNodeID:property.nodeID];
[self.navigationController pushViewController:detailVC animated:YES];
}
}
}
I have the annotation ready to go, but trying to figure out on how to make it draggable with my code:
-(IBAction) updateLocation:(id)sender{
MKCoordinateRegion newRegion;
newRegion.center.latitude = mapView.userLocation.location.coordinate.latitude;
newRegion.center.longitude = mapView.userLocation.location.coordinate.longitude;
newRegion.span.latitudeDelta = 0.0004f;
newRegion.span.longitudeDelta = 0.0004f;
[mapView setRegion: newRegion animated: YES];
CLLocationCoordinate2D coordinate;
coordinate.latitude = mapView.userLocation.location.coordinate.latitude;
coordinate.longitude = mapView.userLocation.location.coordinate.longitude;
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotation setCoordinate: coordinate];
[annotation setTitle: #"Your Car is parked here"];
[annotation setSubtitle: #"Come here for pepsi"];
[mapView addAnnotation: annotation];
[mapView setZoomEnabled: YES];
[mapView setScrollEnabled: YES];
}
Thanks in advance!
To make an annotation draggable, set the annotation view's draggable property to YES.
This is normally done in the viewForAnnotation delegate method.
For example:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString *reuseId = #"pin";
MKPinAnnotationView *pav = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (pav == nil)
{
pav = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
pav.draggable = YES;
pav.canShowCallout = YES;
}
else
{
pav.annotation = annotation;
}
return pav;
}
If you need to handle when the user stops dragging and drops the annotation, see:
how to manage drag and drop for MKAnnotationView on IOS?
In addition, your annotation object (the one that implements MKAnnotation) should have a settable coordinate property. You are using the MKPointAnnotation class which does implement setCoordinate so that part's already taken care of.
please i have recently made a Map which suppose to show the user location (green pin color) and others annotations for service stations (red pins color), for the moment, i am able to show all annotations with the same color and i still unable to tell the MKMapView delegate how to make difference between two pin types and so assign to each type the right title to show.
this is my MKAnnotationView method :
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[MyLocation class]]) {
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [map dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
[annotationView setAnimatesDrop:YES];
annotationView.canShowCallout = YES;
return annotationView;
}
return nil;
}
and for my class which implement the MKAnnotation delegate i have this method :
-(id)initWithName:(NSString *)enseigneDeLaStation distanceVersLaStation:(NSString *) distanceVersLaStation coordinate:(CLLocationCoordinate2D)coordinate
{
if ((self = [super init])) {
_enseigneDeLaStation = [enseigneDeLaStation copy];
_distanceVersLaStation = [distanceVersLaStation copy];
_coordinate = coordinate;
}
return self;
}
thx in advance for your help :)
EDIT
i try to make the user location annotation like this, please if i am wrong correct me :
location2D = (CLLocationCoordinate2D){ .latitude = latitudeOfUserLocation, .longitude = longitudeOfUserLocation };
MyLocation *annotation=[[[MyLocation alloc]initWithName:#"You are here" distanceVersLaStation:#"" coordinate:location2D]autorelease];
[mapView addAnnotation:annotation];
EDIT 2
Hi again, i try to make one annotation to make sure it even call the annotation method so imake this simple example :
latitudeOfUserLocation=43.2923;
longitudeOfUserLocation=5.45427;
location2D = (CLLocationCoordinate2D){ .latitude = latitudeOfUserLocation, .longitude = longitudeOfUserLocation };
MyLocation *annotation=[[[MyLocation alloc]initWithName:#"You are here" distanceVersLaStation:#"coucou" coordinate:location2D]autorelease];
[mapView addAnnotation:annotation];
MKCoordinateSpan span={latitudeDelta:1,longitudeDelta:0.5};
MKCoordinateRegion region={location2D,span};
[mapView setRegion:region];
when i run the app, i see the region zoomed well which go with the 43.2923/5.45427 but i don't see the annotation, why it's not calling the annotation method,i can't move on since it's not showing the user annotation, please help, thx in advance :)
EDIT 3
Hi, i assumed that this has always relation with making difference between user and station pins, so i have declared a var codeColor, set it to 1 (the type of the user) when invoking the annotations and set it to 2(station type) when calling the annotations for the stations :
-(void)viewWillAppear:(BOOL)animated
{
codeColor=1;//it's the first type, the user one
MyLocation *annotation=[[[MyLocation alloc]initWithName:#"You are right here" distanceVersLaStation:#"" coordinate:location2D]autorelease];
annotation.pinColor = MKPinAnnotationColorGreen;
[mapView addAnnotation:annotation];
}
and :
-(void)requestFinished:(ASIHTTPRequest *)request
{ codeColor=2;
[MBProgressHUD hideHUDForView:self.view animated:YES];
MyLocation *annotation=[[[MyLocation alloc]initWithName:ensStation distanceVersLaStation:distance coordinate:location2D]autorelease];
annotation.pinColor = MKPinAnnotationColorPurple;
[mapView addAnnotation:annotation];
}
and for the annotations method :
if (codeColor==2) {
annotationView.rightCalloutAccessoryView=[UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
now when testing for the first time, all is ok, the user annotation without button and the station one is with the button, but when i move from the view and i came back, all annotations are with buttons, even the user one. could you please help me there, thx in advance :)
One simple way is to add a pinColor property to your MyLocation class:
#property (nonatomic, assign) MKPinAnnotationColor pinColor;
When creating the annotation, set the pinColor:
MyLocation *annotation=[[[MyLocation alloc]initWithName:#"You are here" distanceVersLaStation:#"" coordinate:location2D]autorelease];
annotation.pinColor = MKPinAnnotationColorGreen; //or red or whatever
[mapView addAnnotation:annotation];
and in the viewForAnnotation method:
//...
annotationView.canShowCallout = YES;
annotationView.pinColor = ((MyLocation *)annotation).pinColor;