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

#ios #iphone #objective-c #core-location

#iOS #iPhone #objective-c #core-location

Вопрос:

Я добавил экземпляр 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 превращается в серую пунктирную иконку вращения, и исходный значок компаса не восстанавливается.

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

Желаемое поведение такое же, как и в приложении Maps.

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

Восстановлен исходный значок компаса.

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

Ответ №1:

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

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

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

Комментарии:

1. Компас восстанавливается после реализации kCLAuthorizationStatusAuthorized . Если его снова нажать, он превратится в значок вращения. Как обработать это второе нажатие после того, как первый запрос был отклонен?

2. Вы можете реализовать - (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated в своем MKMapViewDelegate. Когда режим меняется на MKUserTrackingModeFollow или MKUserTrackingModeFollowWithHeading и статус из LocationManager не авторизован, вы устанавливаете режим отслеживания MKUserTrackingModeNone так же, как и в другом методе.

3. Я только что попробовал это. Если - (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated реализовано, пользователя больше не просят разрешить / запретить использование текущего местоположения, что означает, что пользователь не уведомлен о том, что нужно сделать.

Ответ №2:

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

         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
    }
}