MKUserTrackingBarButtonItem вращается после того, как приложению запрещено использовать текущее местоположение

Я добавил экземпляр MKUserTrackingBarButtonItem в контроллер представления viewDidLoad следующим образом:

MKUserTrackingBarButtonItem *userTrackingButton = [[MKUserTrackingBarButtonItem alloc] initWithMapView:self->mapView];
NSMutableArray *toolbarItems = [[NSMutableArray alloc] initWithArray:[mapToolBar items]];
[toolbarItems insertObject:userTrackingButton atIndex:0];
[mapToolBar setItems:toolbarItems];

Службы геолокации включены в настройках, но не для приложения. При нажатии кнопки MKUserTrackingBarButtonItem модальное диалоговое окно спрашивает пользователя, разрешить ли приложению использовать текущее местоположение. Когда выбрано «Не разрешать», MKUserTrackingBarButtonItem превращается в вращающийся значок серого пунктира, а исходный значок компаса не восстанавливается.

Как мне восстановить состояние кнопки, как это делается в приложении «Карты»?

Желаемое поведение такое же, как в приложении «Карты».

  1. Убедитесь, что службы геолокации включены в меню «Настройки» > «Конфиденциальность» > «Службы геолокации».
  2. Сбросьте местоположение и конфиденциальность в меню «Настройки» > «Основные» > «Сброс» > «Сбросить местоположение и конфиденциальность».
  3. Запустите приложение «Карты».
  4. Коснитесь значка компаса в левом нижнем углу.
  5. Появится диалоговое окно с сообщением «Карты хотят использовать ваше текущее местоположение». В этот момент значок компаса превратился в серую пунктирную вращающуюся иконку.
  6. Выберите «Не разрешать».

Первоначальный значок компаса восстановлен.

Я тестирую это на iPhone, а не на симуляторе. Приведенный выше код работает без проблем, когда службы определения местоположения включены и приложению разрешено использовать текущее местоположение.


person swifthorseman    schedule 27.06.2014    source источник


Ответы (2)


Реализуйте метод CLLocationManagerDelegate:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status

И когда CLAuthorizationStatus не kCLAuthorizationStatusAuthorized, вы можете обновить свойство userTrackingMode вашего MKMapview до MKUserTrackingModeNone

person olicarbo    schedule 27.06.2014
comment
Компас восстановлен после реализации kCLAuthorizationStatusAuthorized. Если его нажать еще раз, он изменится на вращающийся значок. Как обработать это второе касание после того, как первый запрос был отклонен? - person swifthorseman; 28.06.2014
comment
Вы можете реализовать - (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated в своем MKMapViewDelegate. Когда режим меняется на MKUserTrackingModeFollow или MKUserTrackingModeFollowWithHeading, а статус из LocationManager не авторизован, вы устанавливаете режим отслеживания на MKUserTrackingModeNone, как и в другом методе. - person olicarbo; 28.06.2014
comment
Я только что попробовал это. Если реализован - (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated, пользователю больше не предлагается разрешить/запретить использование текущего местоположения, что означает, что пользователь не уведомляется о том, что необходимо сделать. - person swifthorseman; 28.06.2014

Я не мог найти много помощи по этому вопросу в Интернете, но этот пост очень помог. Вот быстрая реализация того, что сказал Оликарбо:

        func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    mapView.showsUserLocation = (status == .AuthorizedAlways)

    //if location services are turned off for this app.
    if(status == CLAuthorizationStatus.AuthorizedAlways || status == CLAuthorizationStatus.AuthorizedWhenInUse){
        mapView.userTrackingMode = MKUserTrackingMode.None
    }
}

func mapView(mapView: MKMapView, didChangeUserTrackingMode mode: MKUserTrackingMode, animated: Bool) {
    if(CLLocationManager.locationServicesEnabled() == false || !(CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedAlways)){
        //location services are disabled or
        //user has not authorized permissions to use their location.

        mapView.userTrackingMode = MKUserTrackingMode.None
    }
}
person Arthur Garza    schedule 10.01.2016