我有一个UIViewController,我想显示一个以当前位置为中心的地图。
AppDelegate< strong> didFinishLaunchingWithOptions 方法如下所示:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.locationManager = [[CLLocationManager alloc] init];
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
return YES;
}
我的 UIViewController.m 类看起来像这样:
@interface GMapViewController ()<CLLocationManagerDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (strong, nonatomic) CLLocation *currentLocation;
@end
@implementation GMapViewController
#pragma mark - Lifecycle methods
- (void)viewDidLoad {
[super viewDidLoad];
self.currentLocation = [CLLocation new];
[[[AppDelegate appDelegate] locationManager] setDelegate:self];
MKCoordinateRegion visibleRegion;
visibleRegion.center = self.currentLocation.coordinate;
visibleRegion.span = MKCoordinateSpanMake(200, 200);
[self.mapView setRegion:visibleRegion animated:YES];
}
#pragma mark - CLLocationManagerDelegate's methods
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
self.currentLocation = [locations lastObject];
}
事实是CLLocationManager的 didUpdateLocations 委托方法被调用太晚,因为当 viewDidLoad 时 currentLocation 属性没有值被称为。
如何在调用 viewDidLoad 之前获取当前坐标?
答案 0 :(得分:1)
位置更新后,您需要刷新地图视图;这需要一些时间。
您还有潜在的竞争条件,因为您在AppDelegate中调用startUpdatingLocation
,但视图控制器在viewDidLoad
之前未设置为代理。在更新位置之前几乎肯定会设置代表,但您无法保证这一点。
我建议您将所有内容移动到视图控制器中,如果您只想更新一次地图,请使用requestLocation
:
@interface GMapViewController ()<CLLocationManagerDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (strong, nonatomic) CLLocation *currentLocation;
@property (strong, nonatomic) CLLocationManager *locationManager;
@end
@implementation GMapViewController
#pragma mark - Lifecycle methods
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.currentLocation = nil;
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestAlwaysAuthorization];
} else {
[self.locationManager requestLocation];
}
-(void) setMapTo:(CLLocation *)location {
MKCoordinateRegion visibleRegion;
visibleRegion.center =location.coordinate;
visibleRegion.span = MKCoordinateSpanMake(200, 200);
[self.mapView setRegion:visibleRegion animated:YES];
}
#pragma mark - CLLocationManagerDelegate's methods
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *currentLocation = [locations lastObject];
dispatch_async(dispatch_get_main_queue(), ^{
[self setMapTo:currentLocation];
});
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status != kCLAuthorizationStatusRestricted && status != kCLAuthorizationStatusDenied) {
[manager requestLocation];
}
}
如果您只是希望地图能够持续跟踪用户的位置,那么您只需将地图视图的userTrackingMode
属性设置为MKUserTrackingModeFollow