如何在 Xcode 中的 iPhone iOS 6 应用程序上从 A 到 B 获得方向?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12636707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How Can I get Direction on an iPhone iOS 6 App in Xcode from A to B?
提问by TheInterestedOne
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).
我想从 iOS < 6 更新一个使用 Google 地图的应用程序。我的应用程序在地图上有很多图钉,当用户点击其中一个图钉时,iPhone 会像共享应用程序一样调用 Maps,通过本地地图应用程序从他的当前位置和目的地获取方向。对于 iOS 6,相同的说明(在下面发布)显然会打开 Safari 而不是 Google 地图。我想编写一个 if-cycle 来检查设备上安装的 iOS:如果 < 6,没有任何变化,如果 iOS > 6 那么.....(打开新的苹果地图并在那里找到方向)。
Someone can help me please?
有人可以帮我吗?
Here the Action before iOS 6
这里是 iOS 6 之前的 Action
- (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];
}
采纳答案by TheInterestedOne
I've used a preprocessor code like this one posted below to define my condition for the if cycle.
我使用了一个像下面发布的这样的预处理器代码来定义 if 循环的条件。
#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 !
它似乎工作再见!
回答by bromanko
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.
我建议使用 [MKMapItem openMapsWithItems:] 而不是在 iOS 6 中通过 URL 打开地图应用程序。如果您使用 URL,您将无法传递“当前位置”并且将失去进行转弯的能力导航。MKMapItem 有一个当前位置的特定项目,当它被传递时,将使用当前位置作为源地址打开地图,从而启用逐向导航。
- (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]]];
}
}
回答by Roland Keesom
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.
接受的答案对我不起作用。当前位置需要使用正确的语言,而且 ios6 版本也没有正确加载。对我来说,以下工作有效。
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
对于 ios5,我使用这篇文章中的 LocalizedCurrentLocation 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.
对于 ios6,我使用 CLGeocoder 来获取地标,然后用它和当前位置打开地图。
Remember to add CoreLocation.framework and MapKit.framework
记得添加 CoreLocation.framework 和 MapKit.framework
回答by Luca Davanzo
Swift 2.0compatible.
Swift 2.0兼容。
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
}
回答by Mayuri Agrawal
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)
}
}