我希望在任何视图中按下导航栏中的locateButton后更新所有视图中的用户位置。我开始创建一个单身人士。
Location.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
@interface Location : NSObject <CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager* locationManager;
+ (Location*)sharedSingleton;
@end
Location.m
#import "Location.h"
@implementation Location {
CLLocationManager *locationManager;
CLGeocoder *geocoder;
CLPlacemark *placemark;
}
@synthesize locationManager;
- (id)init {
self = [super init];
if(self) {
self.locationManager = [CLLocationManager new];
[self.locationManager setDelegate:self];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
[self.locationManager setHeadingFilter:kCLHeadingFilterNone];
[self.locationManager startUpdatingLocation];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//do any more customization to your location manager
}
return self;
}
+ (Location*)sharedSingleton {
static Location* sharedSingleton;
if(!sharedSingleton) {
@synchronized(sharedSingleton) {
sharedSingleton = [Location new];
}
}
return sharedSingleton;
}
#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 didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(@"didUpdateToLocation: %@", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation != nil) {
latLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
longLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
}
// Stop Location Manager
[locationManager stopUpdatingLocation];
// Reverse Geocoding
NSLog(@"Resolving the Address");
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
if (error == nil && [placemarks count] > 0) {
placemark = [placemarks lastObject];
addressLabel.text = [NSString stringWithFormat:@"%@, %@",
placemark.locality,
placemark.administrativeArea];
addressLabel.numberOfLines = 0;
} else {
NSLog(@"%@", error.debugDescription);
}
} ];
}
@end
我希望在当前视图中按下顶部导航栏中的locationButton时,使用此更新用户lat和long。
- (IBAction)locationPressed:(id)sender {
[[Location sharedSingleton].locationManager startUpdatingLocation];
}
NSNotifications会是最好的吗?如果是这样,我将如何在Location.m和视图控制器中实现它们?感谢。
答案 0 :(得分:3)
我会做的是使用观察者模式。在你的单身人士中,留下所有观察者的NSMutableArray
。
NSMutableArray *observers;
您需要一个所有观察者都遵守的协议:
@protocol LocationObserver <NSObject>
- (void)locationDidChange:(CLLocation *)updatedLocation;
@end
然后当位置发生变化时才这样做
for (id<LocationObserver> observer in observers) {
[observer locationDidChange:newLocation];
}
你应该有一个addObserver和removeObserver方法,它接受id<LocationObserver>
并从数组中添加/删除它。
答案 1 :(得分:0)
这就是我所做的,你可以在github上找到完整的例子https://github.com/irfanlone/CLLocationManager-Singleton-Swift
只需在项目中导入此文件,然后您可以选择实施LocationUpdateProtocol或收听位置更新通知
import MapKit
protocol LocationUpdateProtocol {
func locationDidUpdateToLocation(location : CLLocation)
}
/// Notification on update of location. UserInfo contains CLLocation for key "location"
let kLocationDidChangeNotification = "LocationDidChangeNotification"
class UserLocationManager: NSObject, CLLocationManagerDelegate {
static let SharedManager = UserLocationManager()
private var locationManager = CLLocationManager()
var currentLocation : CLLocation?
var delegate : LocationUpdateProtocol!
private override init () {
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.distanceFilter = kCLLocationAccuracyHundredMeters
locationManager.requestAlwaysAuthorization()
self.locationManager.startUpdatingLocation()
}
// MARK: - CLLocationManagerDelegate
func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) {
currentLocation = newLocation
let userInfo : NSDictionary = ["location" : currentLocation!]
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.delegate.locationDidUpdateToLocation(self.currentLocation!)
NSNotificationCenter.defaultCenter().postNotificationName(kLocationDidChangeNotification, object: self, userInfo: userInfo as [NSObject : AnyObject])
}
}
}
用法:
class ViewController: UIViewController, LocationUpdateProtocol {
var currentLocation : CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "locationUpdateNotification:", name: kLocationDidChangeNotification, object: nil)
let LocationMgr = UserLocationManager.SharedManager
LocationMgr.delegate = self
}
// MARK: - Notifications
func locationUpdateNotification(notification: NSNotification) {
let userinfo = notification.userInfo
self.currentLocation = userinfo!["location"] as! CLLocation
print("Latitude : \(self.currentLocation.coordinate.latitude)")
print("Longitude : \(self.currentLocation.coordinate.longitude)")
}
// MARK: - LocationUpdateProtocol
func locationDidUpdateToLocation(location: CLLocation) {
currentLocation = location
print("Latitude : \(self.currentLocation.coordinate.latitude)")
print("Longitude : \(self.currentLocation.coordinate.longitude)")
}
}