Подтвердить что ты не робот

HowTo инициализирует MKMapView с заданным местоположением пользователя?

Мое приложение знает текущую позицию пользователя (CoreLocation.framework). Как только пользователь откроет новый MapView, его iPhone снова начнет искать текущую позицию. Можно ли пропустить это или изменить первое положение пользователя для mkMapView?

Edit:

Можно ли перезаписать MKMapView и использовать другой LocationManager?

4b9b3361

Ответ 1

Да, возможно иметь отдельный объект диспетчера местоположений и назначить его значение для mapview (BTW, я использую '=' ниже в качестве префикса списка, чтобы предотвратить распространение кода-кода из SO-кода).

= В вашем UIViewController поддерживаются два отдельных свойства: от одного до MKMapView и от одного до CLLocationManager.

= Создайте XIB файл с помощью MKMapView и любого другого хром, который вы хотите. Подключите выходы к контроллерам. Убедитесь, что MKMapView НЕ следует местоположением пользователя.

= Использовать UIViewController протокол CLLocationManagerDelegate, особенно метод locationManager:didUpdateToLocation:fromLocation:, который будет вызываться всякий раз, когда доступно новое значение местоположения. Мы будем устанавливать контроллер в качестве делегата для менеджера местоположений.

= В методе viewController loadView загрузите NIB с помощью MKMapView в нем. Чтобы дать обратную связь с пользователем, вы можете захотеть установить счетчик UIActivityIndicatorView и установить его на startAnimating. Затем вы начинаете с:

self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
self.locationManager.distanceFilter = 10; // or whatever
[self.locationManager startUpdatingLocation];

= В locationManager:didUpdateToLocation:fromLocation: проверьте, обновлено ли событие с последних N секунд. Затем сообщите диспетчеру местоположений о прекращении обновления, счетчик, чтобы остановить анимацию, и получить данные lat/long и назначить его в виде карты вместе с диапазоном просмотра и областью, чтобы он масштабировал и центрировал в нужном месте.

= Теперь здесь сложная часть: синий мрамор "throbber" - это особенность местоположения пользователя отслеживания карт. Вам придется на мгновение "подделать" до тех пор, пока реальный не ударит (или просто используйте отдельный маркер для текущего местоположения и сохраните свою позицию самостоятельно). Лично я бы пошел с синим мрамором, с которым пользователь знаком.

= Чтобы сделать так, чтобы он показывался прямо при запуске, вам нужно создать пользовательский MKAnnotationView с графикой синего мрамора, добавленным в месте, возвращаемом менеджером местоположений. Это означает, что вы делаете снимок Mapview с указанием местоположения, а затем фотографируете только синий мрамор и используете его в качестве изображения для пользовательского представления аннотаций.

= Если вы хотите, чтобы он активно следил за картой, вы можете включить отслеживание пользовательской привязки карты и когда она получит фактические данные, вы спрячете свой ранее установленный маркер и дайте обновлению mapview. Другой вариант - позволить существующему менеджеру местоположений продолжать получать обновления каждую секунду или около того и обновлять положение аннотации синего мрамора самостоятельно.

= Чтобы позволить собственному пользователю mapview userLocation выполнить обновление, добавьте в viewDidLoad:

[self.map.userLocation addObserver:self 
forKeyPath:@"location" 
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
context:NULL];
self.map.showsUserLocation = YES; // starts updating user location

= Реализация observeValueForKeyPath. Он вызывается, когда атрибут location mapview userlocation имеет значение:

-(void)observeValueForKeyPath:(NSString *)keyPath 
      ofObject:(id)object 
        change:(NSDictionary *)change 
       context:(void *)context 
{
     if ([self.map isUserLocationVisible]) {
         [self.locationManager stopUpdatingLocation];
         self.ownBlueMarble.hidden = YES;
     }
     // The current location is in self.map.userLocation.coordinate
}

= Чтобы избежать задержки разминки при отображении текущего местоположения, сохраните ссылку на viewController, содержащую карту и диспетчер местоположений, чтобы она не исчезла (это немного память, но если вы ее отпустите, придется ждать еще раз, пока MapView не загрузит плитки и не будет готов).

= В viewWillLoad вы можете набить последнее известное местоположение в пользовательскую аннотацию bluemarble и показать ее. Включите/выключите отслеживание userLocation, и когда вы получите уведомление, будет работать тот же трюк hide-the-annotation-show-real-marble. Менеджер собственного местоположения mapview запускает и когда у него есть данные, вы можете отключить маркер аннотации.

= Возможно, вы захотите реализовать метод viewController viewWillDisappear и вручную отключите отслеживание userlocation на карте, чтобы оно было отключено по умолчанию при следующем просмотре представления. Вы также захотите получить последний известный userlocation и сохранить его для следующего перехода. Таким образом, вы можете сделать все манипуляции с маркером позиционирования в методе viewWillAppear и не беспокоиться о том, что userLocation вмешивается, пока вы не будете готовы к этому.

Удачи.

Ответ 2

В вашем контроллере:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    CLLocationCoordinate2D coord = {latitude: 37.423617, longitude: -122.220154};
    MKCoordinateSpan span = {latitudeDelta: 1, longitudeDelta: 1};
    MKCoordinateRegion region = {coord, span};
    [mapView setRegion:region];
}

Когда появится карта, она будет находиться по центру рядом с Пало-Альто

Ответ 3

Попробуйте установить для свойства showUserLocation значение false при инициализации, а затем восстановить region ранее имевшийся вид карты (вам, очевидно, придется сохранить это до того, как предыдущая карта будет уничтожена).

Это то, что вы хотели?

Ответ 4

Вам не нужно использовать другой диспетчер местоположений, вы можете добавить любые точки, которые хотите к карте, и обновить их с помощью любой другой логики.

Скажем, у вас было соединение сокета с автомобилем дистанционного управления, и этот автомобиль отправил обратно данные сокетов, содержащие информацию о геопозиции в полезной нагрузке. Вы можете разобрать это и обновить местоположение миниатюры на карте в режиме реального времени. Свойство "userLocation" для этого не требуется, но вы можете показать его, если хотите.

Местоположение пользователя доступно только для чтения, вы можете его использовать или нет. Это не означает, что вам нужен другой менеджер местоположений, чтобы делать все, что вам может понадобиться. Похоже, ваше приложение действительно не нуждается в этой функции, но я мог бы не понимать ваш вопрос.