I'm having issues setting the title and subtitle of my placemark.
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];
placemark.title = #"Some Title";
placemark.subtitle = #"Some subtitle";
MKCoordinateRegion region = self.mapView.region;
region.center = placemark.region.center;
region.span.longitudeDelta /= 8.0;
region.span.latitudeDelta /= 8.0;
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotation:placemark];
}
}
];
placemark.title = #"Some Title"; and placemark.subtitle = #"Some subtitle";
give me an error of:
Assigning to property with 'readonly' attribute not allowed
Why can I not set the Title and Subtitle here?
Thought I'd wake this thread up and give you a solution that I came up with.
As far as I'm aware, MKPlacemark's title/subtitle are readonly properties due to inherent assignment. However, with the solution I found, you can simply pass your MKPlacemark into an MKPointAnnotation as follows:
CLPlacemark *topResult = [placemarks objectAtIndex:0];
// Create an MLPlacemark
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
// Create an editable PointAnnotation, using placemark's coordinates, and set your own title/subtitle
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = #"Sample Location";
point.subtitle = #"Sample Subtitle";
// Set your region using placemark (not point)
MKCoordinateRegion region = self.mapView.region;
region.center = placemark.region.center;
region.span.longitudeDelta /= 8.0;
region.span.latitudeDelta /= 8.0;
// Add point (not placemark) to the mapView
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotation:point];
// Select the PointAnnotation programatically
[self.mapView selectAnnotation:point animated:NO];
Please note that the final [self.mapView selectAnnotation:point animated:NO]; is a workaround to allow automatic popping-up of the placemark. However, the animated:BOOL portion only seems to work with NO in iOS5 - You might want to implement a workaround if you experience issues manually popping up the point-annotation, which can be found here:
MKAnnotation not getting selected in iOS5
I'm sure you've already found your own solution by now, but I hope this is, in some way, informative.
Related
I'm using the below code to display addresses from an array (responseObject) as annotations on my mapview. It works, and the pin is dropped successfully from my location string, however it only shows a pin for the most recent address added to the array. How can I change my code so that it shows pins on the map for all addresses in my array instead of just the most recent one? Apologies if this is a newb question. Thanks!
viewcontroller.m
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:#"u000" forKey:#"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.addressData = [responseObject mutableCopy];
NSString *location = self.addressData[0][#"address"];
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 = self.mapView.region;
// region.center = placemark.region.center;
region.span.longitudeDelta /= 8.0;
region.span.latitudeDelta /= 8.0;
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotation:placemark];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = self.addressData[0][#"users_name"];
point.subtitle = self.addressData[0][#"userbio"];
[self.mapView addAnnotation:point];
You are accessing only one object ?
NSString *location = self.addressData[0][#"address"];
Edited
I think you should handle your data, separated with your view. i.e. implement geocoder related code in the mapView:viewForAnnotation: method in your map view delegate. Then you should be able to create the annotations one by one and use [self.mapView addAnnotations] for all of them
For your code, which I believe is inspired by this answer, you should be able to iterate through all location addresses by something like
for (NSMutableDictionary *loc in self.addressData) {
NSString *loc = location[#"address"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
......
}
Forgive me if the syntax is wrong for Objective C.
I want to search for a destination using the name in MapKit and get back the longitude and latitude (CLLocationCoordinate2D).
Currently I'm using the hardcoded value to set the destination.
// Make a directions request
MKDirectionsRequest *directionsRequest = [MKDirectionsRequest new];
// Start at our current location
MKMapItem *source = [MKMapItem mapItemForCurrentLocation];
[directionsRequest setSource:source];
// Make the destination --> I WANT TO GET THIS COORDINATE USING NAME
CLLocationCoordinate2D destinationCoords = CLLocationCoordinate2DMake(45.545824, 9.327515);
MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:destinationCoords addressDictionary:nil];
MKMapItem *destination = [[MKMapItem alloc] initWithPlacemark:destinationPlacemark];
[directionsRequest setDestination:destination];
You have to use CLGeocoder to forward-geocode using an address:
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:#"New York City" completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
NSLog(#"%#", error);
} else {
CLPlacemark *placemark = [placemarks lastObject];
MKCoordinateRegion region;
region.center.latitude = placemark.location.coordinate.latitude;
region.center.longitude = placemark.location.coordinate.longitude;
[self.mapView setRegion:region animated:YES];
}
}];
This will set the map's region to the location returned, using the latitude and longitude as it's centre.
There must be an easy way to do this or somewhere I am going wrong but I can't seem to save my current location as a global variable and then add it to my array to populate my UITableView.
Basically, at the moment I have an empty UITableView that is used to populate results from a local search, via a search bar. This part works great. BUT, what I want is to always have the 1st row as the users current location, like in maps, google maps, reminders etc. I figured this would be a simple task but I cant get it to work. Can someone help me please.
I use the following code to get my current location, reverse geocode it, and plot it on the map when the app starts:
self.locationManager = [[CLLocationManager alloc]init];
if ([CLLocationManager locationServicesEnabled]) {
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
}
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = _locationManager.location.coordinate.latitude;
zoomLocation.longitude= _locationManager.location.coordinate.longitude;
currentCoord.latitude = _locationManager.location.coordinate.latitude;
currentCoord.longitude= _locationManager.location.coordinate.longitude;
//reverse geocoder
CLLocation *currentLocation = [[CLLocation alloc] initWithLatitude:zoomLocation.latitude longitude:zoomLocation.longitude];
CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark *placemark in placemarks) {
MKPointAnnotation *annotation =
[[MKPointAnnotation alloc]init];
annotation.coordinate = zoomLocation;
annotation.title = #"Current Location";
annotation.subtitle = placemark.name;
// 2
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
// 3
[_mapView setRegion:viewRegion animated:YES];
[_mapView addAnnotation:annotation];
}
}];
When I run my local search I use the following code to populate my array to load the table with:
MKLocalSearchRequest *request =
[[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = _searchBar.text;
request.region = _mapView.region;
MKLocalSearch *search =
[[MKLocalSearch alloc]initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse
*response, NSError *error) {
if (response.mapItems.count == 0)
NSLog(#"No Matches");
else
for (MKMapItem *item in response.mapItems)
{
[tableData addObject:item];
MKPointAnnotation *annotation =
[[MKPointAnnotation alloc]init];
annotation.coordinate = item.placemark.coordinate;
annotation.title = item.placemark.name;
annotation.subtitle = item.placemark.title;
[annotations addObject:annotation];
[_tableResults reloadData];
}
}];
I really can't figure this out. How would I add my current location? Would really appreciate some advise. Thanks in advance guys!
Try this,
[search startWithCompletionHandler:^(MKLocalSearchResponse
*response, NSError *error) {
if (response.mapItems.count == 0)
NSLog(#"No Matches");
else
for (MKMapItem *item in response.mapItems)
{
[tableData addObject:item];
[annotations addObject:[self annotationFromMapItem:item]];
}
double latitude = self.locationManager.location.coordinate.latitude;
double longitude = self.locationManager.location.coordinate.longitude;
MKPlacemark *placemark = [[[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) addressDictionary:nil] autorelease];
MKMapItem *mapItem = [[[MKMapItem alloc] initWithPlacemark:placemark] autorelease];
[mapItem setName:Current Location];
[tableData insertObject:mapItem atIndex:0];
[annotations insertObject:[self annotationFromMapItem:mapItem] atIndex:0];
[_tableResults reloadData];
}];
- (MKPointAnnotation) annotationFromMapItem:(MKMapItem *)item {
MKPointAnnotation *annotation =
[[MKPointAnnotation alloc]init];
annotation.coordinate = item.placemark.coordinate;
annotation.title = item.placemark.name;
annotation.subtitle = item.placemark.title;
return annotation;
}
I followed this question: iOS - MKMapView place annotation by using address instead of lat / long - to create a map annotation for a postal code as opposed to the long/lat values directly.
This works fine, however I would like to set the title and subtitle of the anno
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc]
placemark.title = self.business.businessName;
placemark.subtitle = self.business.phoneNumber;
This is not working as the title and subtitle are readonly. How can I change the above so that I am able to set the title and subtitle?
Use MKPointAnnotation instead.
Sample Code :
CLPlacemark *topresult = [placemarks objectAtIndex:0];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = topresult.location.coordinate;
annotation.title = self.business.businessName;
annotation.subtitle = self.business.phoneNumber;
[self.mapView addAnnotation:annotation];
You can try below code. It may help you.
//set the title if we got any placemarks...
if (placemark.count > 0)
{
CLPlacemark *topResult = [placemark objectAtIndex:0];
annTitle = [NSString stringWithFormat:#"%# %# %# %#", topResult.country, topResult.locality, topResult.subLocality, topResult.thoroughfare];
}
//now create the annotation...
MapAnnotation *toAdd = [[MapAnnotation alloc]init];
toAdd.coordinate = touchMapCoordinate;
toAdd.title = #"Address";
toAdd.subtitle = #"Sub Address";
[self.map addAnnotation:toAdd];
I have this code for my iOS app:
NSString *location = [[NSString alloc] initWithFormat:#"%#, %#", [self.campus campusStreetAddress], [self.campus campusCityStateZip]];
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 = self.campusMap.region;
region.center = placemark.region.center; //DEPRECATED iOS 7
region.span.longitudeDelta /= 1500;
region.span.latitudeDelta /= 1500;
[self.campusMap setRegion:region animated:NO];
[self.campusMap addAnnotation:placemark];
}
}
];
But, when I upgraded my app to iOS 7, placemark.region.center is deprecated. Is there a replacement I should use? Is this even a proper method to creating a map in a view?
Thanks!!
Try this:
region.center = [(CLCircularRegion *)placemark.region center];
if you just want the center of the region you can use :
region.center = placemark.location.coordinate
Combination of Heesien's and other answers and a bit of experimenting.
- (void)centerMapAroundPlacemark:(MKPlacemark *)placemark
{
CLRegion *region = placemark.region;
if ([region isKindOfClass:[CLCircularRegion class]])
{
[self centerMapAroundCircularRegion:(CLCircularRegion *)region
centerCoodinate:placemark.location.coordinate];
}
else
{
[self centerMapAroundCoorinate:placemark.location.coordinate];
}
}
- (void)centerMapAroundCircularRegion:(CLCircularRegion *)circularRegion
{
MKCoordinateRegion coordinateRegion =
MKCoordinateRegionMakeWithDistance(circularRegion.center,
circularRegion.radius,
circularRegion.radius);
[self.mapView setRegion:coordinateRegion animated:YES];
}
- (void)centerMapAroundCircularRegion:(CLCircularRegion *)circularRegion
centerCoodinate:(CLLocationCoordinate2D)centerCoodinate
{
// Only user the radius of region for an appropriate zoom level.
// The center of the region is not accurate.
// To see this search for 'Bath, UK'
MKCoordinateRegion coordinateRegion =
MKCoordinateRegionMakeWithDistance(centerCoodinate,
circularRegion.radius,
circularRegion.radius);
[self.mapView setRegion:coordinateRegion animated:YES];
}