Warning in Custom Map Annotations Iphone

Warning in Custom Map Annotations iPhone

Latitude and Longitude have differing bounds:

  • (-90, 90) for Lat
  • (-180, 180) for Long

Passing a value outside of those bounds will cause the custom class to be deallocated and therefore giving you the error that you're receiving. Make sure that you are passing the correct values for both Latitude and Longitude.

It would be really nice if Apple passed a bounding error for this instead of an early release error. That would've saved me roughly 5 hours worth of time

Error in displaying annotations in map

Because of empty text, it might be converted to 0.000,0.000 or so, better approach is to check [latitude_value.text isEqualToString:@""] and if not then continue with your task. Let me know if this helps.

I guess if this fails, you can just remove all annotations from the map.

Custom title for map annotation

If you want to set a different title and subtitle for each point you'll need to provide a text box for the user to enter the data. Once done it's as simple as the code you already have

NSString *title = [self.titleField stringValue];
[annotation setTitle:@"title"];
NSString *subtitle = [self.subtitleField stringValue];
[annotation setSubtitle:@"title"];

However you may not have the screen space to show three textfields. What I do is create the pin with a default name, then allow the user to open the callout bubble, or open it automatically and show a button to edit it, then show a modal dialog over the top to edit the title and subtitle

If you saved every coordinate.latitude under the key allPins_latitude then each one would overwrite the previous and you'd only have the last one saved. If your pins are all stored as an array, store the array.

iOS Swift MapKit Custom Annotation

I recommend subclassing `MKPointAnnotation.

Pokémon Pin

I have included only the necessary code to display a custom map pin. Think of it as a template.

Outline

  • We will create a point annotation object and assigning a custom image name with the CustomPointAnnotation class.

  • We will subclass the MKPointAnnotation to set image and assign it on the delegate protocol method viewForAnnotation.

  • We will add an annotation view to the map after setting the coordinate of the point annotation with a title and a subtitle.

  • We will implement the viewForAnnotation method which is an MKMapViewDelegate protocol method which gets called for pins to display on the map. viewForAnnotation protocol method is the best place to customise the pin view and assign a custom image to it.

  • We will dequeue and return a reusable annotation for the given identifier and cast the annotation to our custom CustomPointAnnotation class in order to access the image name of the pin.

  • We will create a new image set in Assets.xcassets and place image@3x.png and image@2x.png accordingly.

  • Don't forget plist.

NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription

Sample Image

As always test on a real device.

The swizzle /p>

//1

CustomPointAnnotation.swift

import UIKit
import MapKit

class CustomPointAnnotation: MKPointAnnotation {
var pinCustomImageName:String!
}

//2

ViewController.swift

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

@IBOutlet weak var pokemonMap: MKMapView!
let locationManager = CLLocationManager()
var pointAnnotation:CustomPointAnnotation!
var pinAnnotationView:MKPinAnnotationView!

override func viewDidLoad() {
super.viewDidLoad()

//Mark: - Authorization
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()

pokemonMap.delegate = self
pokemonMap.mapType = MKMapType.Standard
pokemonMap.showsUserLocation = true

}

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = CLLocationCoordinate2D(latitude: 35.689949, longitude: 139.697576)
let center = location
let region = MKCoordinateRegionMake(center, MKCoordinateSpan(latitudeDelta: 0.025, longitudeDelta: 0.025))
pokemonMap.setRegion(region, animated: true)

pointAnnotation = CustomPointAnnotation()
pointAnnotation.pinCustomImageName = "Pokemon Pin"
pointAnnotation.coordinate = location
pointAnnotation.title = "POKéSTOP"
pointAnnotation.subtitle = "Pick up some Poké Balls"

pinAnnotationView = MKPinAnnotationView(annotation: pointAnnotation, reuseIdentifier: "pin")
pokemonMap.addAnnotation(pinAnnotationView.annotation!)
}

func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print(error.localizedDescription)
}

//MARK: - Custom Annotation
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
let reuseIdentifier = "pin"
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseIdentifier)

if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
annotationView?.canShowCallout = true
} else {
annotationView?.annotation = annotation
}

let customPointAnnotation = annotation as! CustomPointAnnotation
annotationView?.image = UIImage(named: customPointAnnotation.pinCustomImageName)

return annotationView
}
}

iphone mkannotation: warning on left callout after map has loaded

If you end up re-using an annotation view, myImageView isn't created, yet you're releasing it. Set myImageView to nil at the top.

- (MKAnnotationView *) mapView:(MKMapView *)thisMapView viewForAnnotation:(MapAnnotations *)annotation {
static NSString *MapIdentifier = @"MapIdentifier";

UIImageView *myImageView = nil;
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[thisMapView dequeueReusableAnnotationViewWithIdentifier:MapIdentifier];

if(annotationView == nil) {
NSString * id = [NSString stringWithFormat:@"%d", (annotation).tag];
NSString * postPhoto = [NSString stringWithFormat:@"id=%@",id];
NSString * hostStrPhoto = @"http://domain.com/get_image.php?";
hostStrPhoto = [hostStrPhoto stringByAppendingString:postPhoto];

NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:hostStrPhoto]];

myImageView = [[UIImageView alloc] initWithImage:[UIImage imageWithData: imgData]];

myImageView.frame = CGRectMake(0,0,31,31);

annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:MapIdentifier] autorelease];
}

annotationView.animatesDrop=TRUE;
annotationView.canShowCallout = YES;
annotationView.leftCalloutAccessoryView = myImageView; //<--where I am getting the error, after all the annotations have loaded.
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

return annotationView;

[myImageView release];
}

Custom Annotation pin interfere with mkmapview's showuserlocation on Iphone

Try this

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;

if ([[annotation title] isEqualToString:@"Destination"])
{
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"greenpin"];
newAnnotation.pinColor = MKPinAnnotationColorGreen;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = YES;
return newAnnotation;
}
}

Obj-C - All Custom MKMapView annotations not always showing on MapView?

You should check if some of your geocoding requests are failing inconsistently.
CLGeocoder rate limits your requests and if you do too many requests in a short time, you'll receive an error. https://developer.apple.com/documentation/corelocation/clgeocoder/1423509-geocodeaddressstring?language=objc

Check if you are getting any reason for failure inside NSError* error inside the completionHandler block.

As many times as it fails, you should see as many less number of annotations on the MapView because it is not entering the following code path.

if (placemarks && placemarks.count > 0) {
// Not entering here
}

if (nil != error) {
// Could land here
}

The only other reason would be not properly calculating map region to show all annotations in screen. Make sure you are calculating/adjusting the region correctly upon each annotation being added to the mapView.

  // Define these variables globally in the view controller
CLLocationDegrees minLatitude = 90.0;
CLLocationDegrees maxLatitude = -90.0;
CLLocationDegrees minLongitude = 180.0;
CLLocationDegrees maxLongitude = -180.0;


// Call following method every time a new annotation needs to be added to the mapView
-(void)addAnnotation:(id<MKAnnotation>)annotation toMapView:(MKMapView*)mapView {
// Add the annotation to map
[mapView addAnnotation:annotation];

// Set the map region to make it visible along with all other annotations
CLLocationDegrees latitude = annotation.coordinate.latitude;
CLLocationDegrees longitude = annotation.coordinate.longitude;

minLatitude = min(minLatitude, latitude);
maxLatitude = max(maxLatitude, latitude);
minLongitude = min(minLongitude, longitude);
maxLongitude = max(maxLongitude, longitude);

CLLocationDegrees latitudeDelta = (maxLatitude - minLatitude);
CLLocationDegrees longitudeDelta = (maxLongitude - minLongitude);

CLLocationDegrees midLatitude = (maxLatitude - latitudeDelta/2);
CLLocationDegrees midLongitude = (maxLongitude - longitudeDelta/2);
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(midLatitude, midLongitude);

MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
MKCoordinateRegion region = MKCoordinateRegionMake(center, span);

if (CLLocationCoordinate2DIsValid(center)) {
[mapView setRegion:region animated:YES];
}
}

Why does a custom MKMapView annotation image disappear on touch?

Answering my own question here, just in case others have the same issue. Notice that I am using "MKPinAnnotationView" - it should be changed to "MKAnnotationView" and everything works.

Fixed code:

- (MKAnnotationView *)mapView:(MKMapView *)newMapView viewForAnnotation:(id )newAnnotation {
MKAnnotationView *annotation = [[MKAnnotationView alloc] initWithAnnotation:newAnnotation reuseIdentifier:@"currentloc"];

if (annotation == nil) {
annotation = [[MKAnnotationView alloc] initWithAnnotation:newAnnotation reuseIdentifier:@"currentloc"];
}

annotation.image = [UIImage imageNamed:@"anno.png"];
annotation.canShowCallout = YES;
annotation.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bus_stop_30x30.png"]];
annotation.leftCalloutAccessoryView = imgView;

return annotation;
}


Related Topics



Leave a reply



Submit