我正在使用核心位置来获取iPhone的位置。我还为我的viewcontroller文件实现了委托协议,并创建了一个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模拟器中运行我的代码..
答案 0 :(得分:4)
来自Apple参考:CLLocationManager
由于返回初始位置可能需要几秒钟,因此位置管理员通常会立即提供以前缓存的位置数据,然后在可用时提供更多最新的位置数据。
另外在另一个堆栈溢出帖子(https://stackoverflow.com/questions/12858548/cllocationmanager-holds-cache-value)中回答,使用CLLocation的timestamp属性来过滤掉返回的旧缓存位置对象。我选择15秒来确保区分缓存的对象,但即使只有几秒钟也可能就足够了:
NSTimeInterval timeInterval = [[location timestamp] timeIntervalSinceNow];
if (abs((NSInteger)timeInterval) < 15)
{
//do something
}
答案 1 :(得分:1)
我想通了,感谢下面其他答案的评论..
在调用[locationManager stopUpdatingLocation];
方法之前,我等待的时间太短了。 GPS需要更多的时间..
所以我在使用NSTimer执行stopUpdatingLocation之前等待。这样做了。感谢gWiz!
答案 2 :(得分:0)
我认为,在Xcode中设置了一个不同的位置作为模拟位置,这就是模拟器向您显示的内容。先检查一下。模拟器不会显示您当前的位置,它会将在Xcode中设置的位置显示为模拟位置。只有设备才能显示您的真实位置。希望它有所帮助。
答案 3 :(得分:0)
这可能是因为您正在尝试从didUpdateLocations
内部更新UI,这肯定会在主线程之外的另一个线程上运行。
改变这个:
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];
});
}
答案 4 :(得分: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];
}
答案 5 :(得分:0)
CLLocationManager会缓存您的位置数据。 一种有用的方法是检查更新之间的时间间隔。 您将获得每个位置更新的时间戳。 使用此比较旧位置时间戳和新位置时间戳 [newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp]并在interval大于5的情况下丢弃这些更新。