【问题标题】:How to get CLLocationManager's current coordinate如何获取 CLLocationManager 当前坐标
【发布时间】:2018-06-10 12:52:26
【问题描述】:

我有一个 UIViewController,我想在其中显示以当前位置为中心的地图。

AppDelegate 的 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 委托方法调用太晚,因为调用 viewDidLoadcurrentLocation 属性没有值。

如何在调用 viewDidLoad 之前获取当前坐标?

【问题讨论】:

  • 为什么不直接在视图控制器中导入 CoreLocation?
  • CoreLocation 已导入 AppDelegate
  • GMapViewController 中的 viewDidLoad 很可能比 AppDelegate 中的 didFinishLaunchingWithOptions 更早被调用。懒惰地初始化locationManager,设置委托后将startUpdatingLocation移动到viewDidLoad
  • @vadian,didFinishLaunchingWithOptions 的调用早于 viewDidLoad
  • “如何在调用 viewDidLoad 之前获取当前坐标” - 你不能也不应该尝试。调用 didUpdateLocations 时更新地图的区域。在发生之前展示一些合理的东西。

标签: ios objective-c cllocationmanager cllocation


【解决方案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

【讨论】:

    猜你喜欢
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    相关资源
    最近更新 更多