3

我正在使用核心位置来获取 iphone 的位置。我还为我的视图控制器文件实现了委托协议,并创建了一个 CLLocationmanager 对象。

当我按下按钮(IBAction)时,我希望更新位置。代表被正确调用。我可以看到,因为 NSLog 消息与纬度/经度坐标一起出现。

但是当我在 IOS 模拟器中更改位置并尝试使用按钮再次访问该位置时,我得到的位置输出保持不变。我必须再次按下按钮才能获得正确的位置。显然,我希望第一次按下按钮时位置就正确

这是我触发委托的按钮:

- (IBAction)getLocation:(id)sender {


[locationManager startUpdatingLocation];
}

我的 viewDidLoad 中有这段代码

locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;

这是我的委托方法:

#pragma mark - CLLocationManagerDelegate 
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"didFailWithError: %@", error);
UIAlertView *errorAlert = [[UIAlertView alloc]
                           initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
 }

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
NSLog(@"didUpdateToLocation: %@", [locations lastObject]);
CLLocation *currentLocation = [locations lastObject];


if (currentLocation != nil) {
    _longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
    _latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
   }
[locationManager stopUpdatingLocation];
}

我在 Iphone 6.1 模拟器中运行我的代码..

4

6 回答 6

4

来自 Apple 参考:CLLocationManager

因为返回初始位置可能需要几秒钟,所以位置管理器通常会立即提供先前缓存的位置数据,然后在可用时提供更多最新的位置数据。

还在另一个堆栈溢出帖子 ( https://stackoverflow.com/questions/12858548/cllocationmanager-holds-cache-value ) 中回答,使用 CLLocation 的时间戳属性过滤掉返回的旧缓存位置对象。我选择了 15 秒来确保区分缓存对象,但即使只有几秒钟也可能就足够了:

NSTimeInterval timeInterval = [[location timestamp] timeIntervalSinceNow];
if (abs((NSInteger)timeInterval) < 15)
{
    //do something
}
于 2014-02-10T19:42:48.400 回答
1

我想通了,感谢其他答案下面的评论..

[locationManager stopUpdatingLocation];在调用该方法之前,我等待的时间太短了 。GPS只是需要更多时间..

所以我只是在使用 NSTimer 执行 stopUpdatingLocation 之前等待。那完成了工作。感谢 gWiz!

于 2013-10-19T16:32:42.137 回答
0

我认为,已经在您的 Xcode 中设置了一个不同的位置作为模拟位置,这就是模拟器向您显示的内容。先检查一下。模拟器不会显示您当前的位置,它会将 Xcode 中设置的位置显示为模拟位置。只有设备可以显示您的真实位置。希望能帮助到你。

于 2013-10-14T15:28:07.497 回答
0

这可能是因为您正在尝试从内部更新 UI,该 UIdidUpdateLocations肯定在主线程之外的另一个线程上运行。

改变这个:

if (currentLocation != nil) {
_longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
_latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
}

对此:

if (currentLocation != nil) {
    dispatch_async(dispatch_get_main_queue(), ^{
        _longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
        _latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
    });
}
于 2013-10-14T15:31:05.990 回答
0

在 iOS6 中尝试此代码 Apple 希望我们使用 didUpdateLocations 而不是 didUpdateToLocation

.h file


    CLLocationManager *locationManager;


.m File

  // get the current location latitude and longitude

    // locationManager update as location
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    locationManager.distanceFilter = kCLDistanceFilterNone;
    [locationManager startUpdatingLocation];

    CLLocation *location = [locationManager location];


    locationManager.delegate=self;

    //Get user location
    [locationManager startUpdatingLocation];

    // Configure the new event with information from the location
    CLLocationCoordinate2D coordinate = [location coordinate];

    NSString *latitude = [NSString stringWithFormat:@"%f", coordinate.latitude];
    NSString *longitude = [NSString stringWithFormat:@"%f", coordinate.longitude];

    NSLog(@"dLatitude : %@", latitude);
    NSLog(@"dLongitude : %@",longitude);


- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation{

[locations lastObject];

}

于 2013-10-14T16:58:07.733 回答
0

CLLocationManager 确实会缓存您的位置数据。一个有用的方法是检查更新之间的时间间隔。您将获得每个位置更新的时间戳。使用此 [newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp] 比较新旧位置时间戳,如果间隔大于 5 左右,则丢弃这些更新。

于 2013-10-15T12:19:34.267 回答