可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to update an app from iOS < 6 that uses Google Maps. My app has a lot of pins on a map, and, when a user taps over one of them, the iPhone call Maps like a shared application to get direction from his current location and the destination with the native Maps App. With iOS 6, the same instructions (posted below) obviously open Safari instead Google Maps. I want to write an if-cycle that checks the iOS installed on the device: if < 6, nothing changed, if iOS > 6 then..... (open new apple maps and get direction there).
Someone can help me please?
Here the Action before iOS 6
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
[self.navigationController pushViewController:[[UIViewController alloc] init] animated:YES];
NSString* addr = [NSString stringWithFormat:@"http://maps.google.com/maps?daddr=%1.6f,%1.6f&saddr=Posizione attuale", view.annotation.coordinate.latitude,view.annotation.coordinate.longitude];
NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:url];
}
回答1:
I recommend using [MKMapItem openMapsWithItems:] instead of opening the maps app via a URL in iOS 6. If you use a URL, you will not be able to pass "Current Location" and will lose the ability to do turn-by-turn navigation. MKMapItem has a specific item for current location that, when passed, will open Maps using Current Location as the source address thus enabling turn-by-turn navigation.
- (void)openMapsWithDirectionsTo:(CLLocationCoordinate2D)to {
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) {
MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];
MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[[MKPlacemark alloc] initWithCoordinate:to addressDictionary:nil] autorelease]];
toLocation.name = @"Destination";
[MKMapItem openMapsWithItems:[NSArray arrayWithObjects:currentLocation, toLocation, nil]
launchOptions:[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:MKLaunchOptionsDirectionsModeDriving, [NSNumber numberWithBool:YES], nil]
forKeys:[NSArray arrayWithObjects:MKLaunchOptionsDirectionsModeKey, MKLaunchOptionsShowsTrafficKey, nil]]];
[toLocation release];
} else {
NSMutableString *mapURL = [NSMutableString stringWithString:@"http://maps.google.com/maps?"];
[mapURL appendFormat:@"saddr=Current Location"];
[mapURL appendFormat:@"&daddr=%f,%f", to.latitude, to.longitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[mapURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
}
}
回答2:
I've used a preprocessor code like this one posted below to define my condition for the if cycle.
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
Then:
if (SYSTEM_VERSION_LESS_THAN(@"6.0")) {
NSString* addr = [NSString stringWithFormat:@"http://maps.google.com/maps?daddr=%1.6f,%1.6f&saddr=Posizione attuale", view.annotation.coordinate.latitude,view.annotation.coordinate.longitude];
NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:url];
}
else {
NSString* addr = [NSString stringWithFormat:@"http://maps.apple.com/maps?daddr=%1.6f,%1.6f&saddr=Posizione attuale", view.annotation.coordinate.latitude,view.annotation.coordinate.longitude];
NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:url];
}
It seems to work
Bye !
回答3:
The accepted answer didn't work for me. The Current Location needs to be in the correct language and also the ios6 version didn't load correctly. For me the following worked.
NSString *destinationAddress = @"Amsterdam";
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:destinationAddress completionHandler:^(NSArray *placemarks, NSError *error) {
if([placemarks count] > 0) {
MKPlacemark *placeMark = [[MKPlacemark alloc] initWithPlacemark:[placemarks objectAtIndex:0]];
MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:placeMark];
MKMapItem *mapItem2 = [MKMapItem mapItemForCurrentLocation];
NSArray *mapItems = @[mapItem, mapItem2];
NSDictionary *options = @{
MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsMapTypeKey:
[NSNumber numberWithInteger:MKMapTypeStandard],
MKLaunchOptionsShowsTrafficKey:@YES
};
[MKMapItem openMapsWithItems:mapItems launchOptions:options];
} else {
//error nothing found
}
}];
return;
} else {
NSString *sourceAddress = [LocalizedCurrentLocation currentLocationStringForCurrentLanguage];
NSString *urlToOpen = [NSString stringWithFormat:@"http://maps.google.com/maps?saddr=%@&daddr=%@",
[sourceAddress stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[destinationAddress stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlToOpen]];
}
For ios5 I use the LocalizedCurrentLocation from this post http://www.martip.net/blog/localized-current-location-string-for-iphone-apps
For ios6 I use the CLGeocoder to get the placemark and then open the map with it and the current location.
Remember to add CoreLocation.framework and MapKit.framework
回答4:
Swift 2.0 compatible.
I didn't find any exhaustive answer yet.
/**
Try to open google maps with navigation feature and with given coordinates
- parameter latitude: destination latitude
- parameter longitude: destination longitude
- parameter destinationName: destination name
- parameter completion: completion callback
*/
static func openGoogleMapsNavigation(latitude: Double, longitude: Double, destinationName: String, completion: ((error: NSError?) -> (Void))?) {
let directionRequest: MKDirectionsRequest = MKDirectionsRequest()
let destination = Utils.createMapItem(name: destinationName, latitude: latitude, longitude: longitude)
directionRequest.source = MKMapItem.mapItemForCurrentLocation()
directionRequest.destination = destination
directionRequest.transportType = MKDirectionsTransportType.Automobile
directionRequest.requestsAlternateRoutes = true
let directions: MKDirections = MKDirections(request: directionRequest)
directions.calculateDirectionsWithCompletionHandler { (response: MKDirectionsResponse?, error: NSError?) -> Void in
if error == nil {
destination.openInMapsWithLaunchOptions([ MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving])
}
completion?(error: error)
}
}
Where I have this utility method:
static func createMapItem(name name: String, latitude: Double, longitude: Double) -> MKMapItem {
let coordinates = CLLocationCoordinate2DMake(latitude, longitude)
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = name
return mapItem
}
回答5:
For people searching for an answer in swift -
//MARK:- ViewDidLoad
let directionRequest = MKDirectionsRequest()
directionRequest.source = self.sourceMapitem
directionRequest.destination = self.destinationMapitem
directionRequest.transportType = .Automobile
// where sourceMapitem and destinationMapitem are MKMapItem
let directions = MKDirections(request: directionRequest)
directions.calculateDirectionsWithCompletionHandler {
(response, error) -> Void in
if response != nil {
let route = response!.routes[0]
self.myMapView.addOverlay((route.polyline), level: MKOverlayLevel.AboveRoads)
print("OVER")
}
else{
print(" ERROR: \(error)")
}
}
//MARK:- DefineFunctions
func showRoute(response: MKDirectionsResponse) {
for route in response.routes {
myMapView.addOverlay(route.polyline,
level: MKOverlayLevel.AboveRoads)
}
}