如何仅在按下按钮时更新位置

Posted

技术标签:

【中文标题】如何仅在按下按钮时更新位置【英文标题】:How to update location only when button is pressed 【发布时间】:2011-09-29 14:00:41 【问题描述】:

如何让我的应用程序仅在按下按钮时更新位置?

我有一个名为“REFRESH”的按钮。每次按下此按钮时,我都想向我的用户显示他们的位置。例如,51 Bourke Street, Victoria

但是,我不想定期更新我的位置。我只想在按下按钮时更新它的位置,以节省电池电量。

你怎么看?我做得对吗?

我有这些课程:

VoteViewController.h 和 VoteViewController.m CoreLocationController.h 和 CoreLocationController.m

这就是我所拥有的:

VoteViewController.h

@interface VoteViewController : UIViewController <CoreLocationControllerDelegate> 

    CoreLocationController *coreController;


- (void)locationUpdate:(CLLocation *)location; 
- (void)locationError:(NSError *)error;
- (void)geoReverseAddress:(MKPlacemark *)placeMark;
- (IBAction)refreshButtonPressed;

VoteViewController.m

- (void)viewDidLoad

    [super viewDidLoad];
    coreController = [[CoreLocationController alloc] init];
    coreController.delegate = self;


- (IBAction)refreshButtonPressed

    NSLog(@"Refresh Button pressed");
    label.text = [NSString stringWithString:@""];
    [coreController.locationManager startUpdatingLocation];


- (void)locationUpdate:(CLLocation *)location 

    comments.text = [location description];
    [coreController.locationManager stopUpdatingLocation];


- (void)locationError:(NSError *)error 

    comments.text = [error description];
    [coreController.locationManager stopUpdatingLocation];


- (void)geoReverseAddress:(MKPlacemark *)placeMark

    label.text = [NSString stringWithFormat:@"%@ %@, %@", [placeMark subThoroughfare], 
[placeMark thoroughfare], [placeMark locality]]; 

CoreLocationController.h

@protocol CoreLocationControllerDelegate <NSObject>

@required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
- (void)geoReverseAddress:(MKPlacemark *)placeMark;

@end

@interface CoreLocationController : NSObject <CLLocationManagerDelegate, MKReverseGeocoderDelegate>

    CLLocationManager *locationManager;
    id delegate;

    MKReverseGeocoder *reverse;


@property(nonatomic, retain) CLLocationManager *locationManager;
@property(nonatomic, retain) id delegate;
@end

CoreLocationController.m

-(id) init

    self = [super init];

    if (self != nil)
    
        self.locationManager = [[[CLLocationManager alloc] init] autorelease];
        self.locationManager.delegate = self;
        self.locationManager.distanceFilter = kCLHeadingFilterNone;
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    
    return self;


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

    NSLog(@"Update location");
    [self.delegate locationUpdate:newLocation];

    reverse = [[MKReverseGeocoder alloc] initWithCoordinate:[newLocation coordinate]];
    reverse.delegate = self;
    [reverse start];


- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

    [self.delegate locationError:error];


- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error

    [self.delegate locationError:error];
    [reverse cancel];
    [reverse release];


- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark

    [self.delegate geoReverseAddress:placemark];
    [reverse cancel];
    [reverse release];

【问题讨论】:

【参考方案1】:

当您第一次启动 CLLocationManager 时,您很可能会从上次运行时获得一个陈旧的位置。一旦解决了这个问题,您将开始获得非常不准确的位置,而设备使用 WiFi 嗅探和小区三角测量,而 GPS 正在寻找解决方案。

因此,在您的 didUpdateToLocation 方法中,您可能希望丢弃第一个命中,然后测试您的 newLocation 对象的 .horizo​​ntalAccuracy 值以获得足够低的值以供信任。

除此之外,我看不出你发来的东西有什么不好的地方。我不确定我是否会麻烦将位置获取工作包装在它自己的类中,我可能只是在我的 viewController 中做到这一点。但这是一种风格选择。如果您要在其他地方重用此功能,那么您所拥有的显然是可行的方法。

【讨论】:

Dan Rey,我的代码的问题是它在我第一次运行它时可以工作(比如我的房子)。但是,当我尝试在另一个地方运行它时(比如我朋友的房子) ).. 这没用。 :( 它仍然会显示我的旧位置(在这种情况下是我的房子)。希望我说清楚。 这是有道理的,返回的第一个位置通常是上次获取您的位置时的缓存位置...这就是为什么它会显示您仍在您家中的原因。例如,您可以检查收到的位置的时间戳,并丢弃任何超过 3 分钟的时间(我相信这是 Apple 在其文档中使用的时间长度)。

以上是关于如何仅在按下按钮时更新位置的主要内容,如果未能解决你的问题,请参考以下文章

如何在按下按钮后每 10 分钟重复一次方法并在按下另一个按钮时结束它

输入类型按钮在按下时会改变颜色?

如何在按下按钮时从UITextField更新标签

WPF Focused Visual State 仅在按下按钮时才会启动,为啥?

迅速!仅在按下按钮时创建一个segue!标签栏控制器

如何仅在按下键时更改值?