MKMapView 或 CLLocationManger - 确定用户的当前位置
MKMapView or CLLocationManger - to determine user's current location
有两个 类 有助于绘制地图和确定用户位置 - MKMapView
和 CLLocationManager
。
MKMapView
有一个代表“didUpdateUserLocation
”,告诉用户当前位置。同时,CLLocationManger
有一个委托“didUpdateToLocation
”,它也做同样的事情。
我的问题是何时使用 MKMapView
和 CLLocationManager
。我可以从 MKMapView
获取设备的当前位置,那么为什么以及何时应该使用 CLLocationManager
?我试图得到它,但我仍然不确定。
我认为您混淆了 MKMapView
属性 showsUserLocation 和 CLLocationManager
。
为方便起见,MKMapView 允许您简单地启用 属性 来向用户显示地图上的当前位置 UI。如果您只需要向用户显示他们在地图上的位置,这将非常方便。
然而,显然还有许多其他用例,仅在地图上显示位置是不够的,这就是 CLLocationManager
的用武之地。
例如考虑一个 running/training 应用程序,其中需要用户位置记录来计算 运行 距离,或者甚至是我自己的应用程序之一的示例,我需要在其中找到用户位置 (lat/long) 以实时计算到各个火车站的距离,以确定离用户最近的火车站。在这些示例中,不需要 MapView,因此使用 LocationManager 是正确的选择。
任何时候您需要以编程方式与用户位置交互并且基本上不需要地图 UI!
我更喜欢使用 MKMapView 内部使用的 CLLocationManager,所以如果您不需要使用地图,只需使用位置管理器中的以下代码即可。
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.delegate = self;
[locationManager startUpdatingLocation];
只是不要忘记将 locationManager 实例存储在您的 class 中的某处,您可以像这样实现委托。
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"Error detecting location %@", error);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation* location = (CLLocation*)locations.lastObject;
NSLog(@"Longitude: %f, Latitude: %f", location.coordinate.longitude, location.coordinate.latitude);
}
编辑
您可以使用 Apple 的地理编码器根据用户的位置获取用户的地址
// Use Apple's Geocoder to figure the name of the place
CLGeocoder* geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:location completionHandler: ^(NSArray* placemarks, NSError* error) {
if (error != nil) {
NSLog(@"Error in geo coder: %@", error);
}
else {
if (placemarks.count == 0) {
NSLog(@"The address couldn't be found");
}
else {
// Get nearby address
CLPlacemark* placemark = placemarks[0];
// Get the string address and store it
NSString* locatedAt = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];
location.name = locatedAt;
NSLog(@"The address is: %@", locatedAt);
}
}
}];
有两个 类 有助于绘制地图和确定用户位置 - MKMapView
和 CLLocationManager
。
MKMapView
有一个代表“didUpdateUserLocation
”,告诉用户当前位置。同时,CLLocationManger
有一个委托“didUpdateToLocation
”,它也做同样的事情。
我的问题是何时使用 MKMapView
和 CLLocationManager
。我可以从 MKMapView
获取设备的当前位置,那么为什么以及何时应该使用 CLLocationManager
?我试图得到它,但我仍然不确定。
我认为您混淆了 MKMapView
属性 showsUserLocation 和 CLLocationManager
。
为方便起见,MKMapView 允许您简单地启用 属性 来向用户显示地图上的当前位置 UI。如果您只需要向用户显示他们在地图上的位置,这将非常方便。
然而,显然还有许多其他用例,仅在地图上显示位置是不够的,这就是 CLLocationManager
的用武之地。
例如考虑一个 running/training 应用程序,其中需要用户位置记录来计算 运行 距离,或者甚至是我自己的应用程序之一的示例,我需要在其中找到用户位置 (lat/long) 以实时计算到各个火车站的距离,以确定离用户最近的火车站。在这些示例中,不需要 MapView,因此使用 LocationManager 是正确的选择。
任何时候您需要以编程方式与用户位置交互并且基本上不需要地图 UI!
我更喜欢使用 MKMapView 内部使用的 CLLocationManager,所以如果您不需要使用地图,只需使用位置管理器中的以下代码即可。
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.delegate = self;
[locationManager startUpdatingLocation];
只是不要忘记将 locationManager 实例存储在您的 class 中的某处,您可以像这样实现委托。
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"Error detecting location %@", error);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation* location = (CLLocation*)locations.lastObject;
NSLog(@"Longitude: %f, Latitude: %f", location.coordinate.longitude, location.coordinate.latitude);
}
编辑
您可以使用 Apple 的地理编码器根据用户的位置获取用户的地址
// Use Apple's Geocoder to figure the name of the place
CLGeocoder* geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:location completionHandler: ^(NSArray* placemarks, NSError* error) {
if (error != nil) {
NSLog(@"Error in geo coder: %@", error);
}
else {
if (placemarks.count == 0) {
NSLog(@"The address couldn't be found");
}
else {
// Get nearby address
CLPlacemark* placemark = placemarks[0];
// Get the string address and store it
NSString* locatedAt = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];
location.name = locatedAt;
NSLog(@"The address is: %@", locatedAt);
}
}
}];