NIMLocationViewController.m 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. //
  2. // NTESLocationViewController.m
  3. // NIM
  4. //
  5. // Created by chris on 15/2/28.
  6. // Copyright (c) 2015年 Netease. All rights reserved.
  7. //
  8. #import "NIMLocationViewController.h"
  9. #import "NIMKitDependency.h"
  10. #import "NIMKitLocationPoint.h"
  11. #import <AddressBookUI/AddressBookUI.h>
  12. #import <CoreLocation/CoreLocation.h>
  13. @interface NIMLocationViewController () <CLLocationManagerDelegate>
  14. {
  15. BOOL _updateUserLocation;
  16. }
  17. @property(nonatomic,strong) UIBarButtonItem *sendButton;
  18. @property(nonatomic,strong) CLLocationManager *locationManager;
  19. @property(nonatomic,strong) NIMKitLocationPoint *locationPoint;
  20. @property(nonatomic,strong) CLGeocoder * geoCoder;
  21. @end
  22. @implementation NIMLocationViewController
  23. - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
  24. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  25. if (self) {
  26. _locationManager = [[CLLocationManager alloc] init];
  27. _geoCoder = [[CLGeocoder alloc] init];
  28. }
  29. return self;
  30. }
  31. - (instancetype)initWithLocationPoint:(NIMKitLocationPoint *)locationPoint{
  32. self = [self initWithNibName:nil bundle:nil];
  33. if (self) {
  34. _locationPoint = locationPoint;
  35. }
  36. return self;
  37. }
  38. - (void)viewDidLoad {
  39. [super viewDidLoad];
  40. self.navigationItem.title = @"位置";
  41. self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(dismiss:)];
  42. self.mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
  43. self.mapView.delegate = self;
  44. [self.view addSubview:self.mapView];
  45. if (self.locationPoint) {
  46. MKCoordinateRegion theRegion;
  47. theRegion.center = self.locationPoint.coordinate;
  48. theRegion.span.longitudeDelta = 0.01f;
  49. theRegion.span.latitudeDelta = 0.01f;
  50. [self.mapView addAnnotation:self.locationPoint];
  51. [self.mapView setRegion:theRegion animated:YES];
  52. }else{
  53. [self setUpRightNavButton];
  54. self.locationPoint = [[NIMKitLocationPoint alloc] init];
  55. self.locationManager = [CLLocationManager new];
  56. [self.locationManager requestWhenInUseAuthorization];
  57. self.locationManager.delegate = self;
  58. if ([CLLocationManager locationServicesEnabled]) {
  59. [_locationManager requestWhenInUseAuthorization];
  60. CLAuthorizationStatus status = CLLocationManager.authorizationStatus;
  61. if (status == kCLAuthorizationStatusRestricted || status == kCLAuthorizationStatusDenied) {
  62. [self.view makeToast:@"请在设置-隐私里允许程序使用地理位置服务"
  63. duration:2
  64. position:CSToastPositionCenter];
  65. }else{
  66. self.mapView.showsUserLocation = YES;
  67. }
  68. }else{
  69. [self.view makeToast:@"请打开地理位置服务"
  70. duration:2
  71. position:CSToastPositionCenter];
  72. }
  73. }
  74. }
  75. - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
  76. }
  77. - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations {
  78. }
  79. - (void)setUpRightNavButton{
  80. UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(onSend:)];
  81. self.navigationItem.rightBarButtonItem = item;
  82. self.sendButton = item;
  83. self.sendButton.enabled = NO;
  84. }
  85. - (void)onSend:(id)sender{
  86. if ([self.delegate respondsToSelector:@selector(onSendLocation:)]) {
  87. [self.delegate onSendLocation:self.locationPoint];
  88. }
  89. [self.navigationController dismissViewControllerAnimated:YES completion:nil];
  90. }
  91. - (void)didReceiveMemoryWarning {
  92. [super didReceiveMemoryWarning];
  93. }
  94. #pragma mark - MKMapViewDelegate
  95. - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
  96. if (!_updateUserLocation) {
  97. return;
  98. }
  99. CLLocationCoordinate2D centerCoordinate = mapView.region.center;
  100. [self reverseGeoLocation:centerCoordinate];
  101. }
  102. - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
  103. {
  104. if (!_updateUserLocation) {
  105. return;
  106. }
  107. [_mapView removeAnnotations:_mapView.annotations];
  108. }
  109. - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
  110. static NSString *reusePin = @"reusePin";
  111. MKPinAnnotationView * pin = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:reusePin];
  112. if (!pin) {
  113. pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reusePin];
  114. }
  115. pin.canShowCallout = YES;
  116. return pin;
  117. }
  118. - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
  119. _updateUserLocation = YES;
  120. MKCoordinateRegion theRegion;
  121. theRegion.center = userLocation.coordinate;
  122. theRegion.span.longitudeDelta = 0.01f;
  123. theRegion.span.latitudeDelta = 0.01f;
  124. [_mapView setRegion:theRegion animated:NO];
  125. }
  126. - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views{
  127. [_mapView selectAnnotation:self.locationPoint animated:YES];
  128. UIView * view = [mapView viewForAnnotation:self.mapView.userLocation];
  129. view.hidden = YES;
  130. }
  131. - (void)reverseGeoLocation:(CLLocationCoordinate2D)locationCoordinate2D{
  132. if (self.geoCoder.isGeocoding) {
  133. [self.geoCoder cancelGeocode];
  134. }
  135. CLLocation *location = [[CLLocation alloc]initWithLatitude:locationCoordinate2D.latitude
  136. longitude:locationCoordinate2D.longitude];
  137. __weak NIMLocationViewController *wself = self;
  138. self.sendButton.enabled = NO;
  139. [self.geoCoder reverseGeocodeLocation:location
  140. completionHandler:^(NSArray *placemarks, NSError *error)
  141. {
  142. if (error == nil) {
  143. CLPlacemark *mark = [placemarks lastObject];
  144. NSString * title = [wself nameForPlaceMark:mark];
  145. NIMKitLocationPoint *ponit = [[NIMKitLocationPoint alloc]initWithCoordinate:locationCoordinate2D andTitle:title];
  146. wself.locationPoint = ponit;
  147. [wself.mapView addAnnotation:ponit];
  148. wself.sendButton.enabled = YES;
  149. } else {
  150. wself.locationPoint = nil;
  151. }
  152. }];
  153. }
  154. - (NSString *)nameForPlaceMark: (CLPlacemark *)mark
  155. {
  156. NSString *name = ABCreateStringWithAddressDictionary(mark.addressDictionary,YES);
  157. unichar characters[1] = {0x200e}; //format之后会出现这个诡异的不可见字符,在android端显示会很诡异,需要去掉
  158. NSString *invalidString = [[NSString alloc]initWithCharacters:characters length:1];
  159. NSString *formattedName = [[name stringByReplacingOccurrencesOfString:@"\n" withString:@" "]
  160. stringByReplacingOccurrencesOfString:invalidString withString:@""];
  161. return formattedName;
  162. }
  163. - (void)dismiss:(id)sender
  164. {
  165. if (self.navigationController.presentingViewController) {
  166. [self.navigationController dismissViewControllerAnimated:YES completion:nil];
  167. }else{
  168. [self.navigationController popViewControllerAnimated:YES];
  169. }
  170. }
  171. @end