#ios #mapkit
#iOS #mapkit
Вопрос:
Моя цель — создать карту, на которой местоположение пользователя отображается с аннотацией и масштабированием, все в порядке, местоположение там с красной аннотацией и хорошим масштабированием, для этого у меня есть представление, которое называется PositionActuelleViewController, вот мой код :
PositionActuelleViewController.h :
@interface PositionActuelleViewController : UIViewController<MKMapViewDelegate,CLLocationManagerDelegate> {
MKMapView *mapView;
MKReverseGeocoder *geoCoder;
MKPlacemark *mPlacemark;
CLLocationCoordinate2D location;
}
@property (nonatomic,retain)IBOutlet MKMapView *mapView;
@end
PositionActuelleViewController.m :
- (void)viewDidLoad {
[super viewDidLoad];
[mapView setShowsUserLocation:TRUE];
[mapView setMapType:MKMapTypeStandard];
[mapView setDelegate:self];
[self.view insertSubview:mapView atIndex:0];
CLLocationManager *locationManager=[[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
location = newLocation.coordinate;
MKCoordinateRegion region;
region.center = location;
MKCoordinateSpan span;
span.latitudeDelta = .005;
span.longitudeDelta = .005;
region.span = span;
[mapView setRegion:region animated:TRUE];
}
Моя единственная проблема в том, что увеличение всегда включено, даже если пользователь уменьшает масштаб карты, он увеличивается автоматически. Как я могу это исправить?
Ответ №1:
Если вы хотите увеличить масштаб только один раз, вы можете добавить логический параметр ivar с именем didZoomToUserLocation, например.
В viewDidLoad
инициализируйте его значением NO перед вызовом startUpdatingLocation
:
didZoomToUserLocation = NO;
[locationManager startUpdatingLocation];
Затем в didUpdateToLocation
измените код следующим образом:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
location = newLocation.coordinate;
if (didZoomToUserLocation)
return;
didZoomToUserLocation = YES;
MKCoordinateRegion region;
region.center = location;
MKCoordinateSpan span;
span.latitudeDelta = .005;
span.longitudeDelta = .005;
region.span = span;
[mapView setRegion:region animated:TRUE];
}
Обратите внимание, что при этом также прекратится отслеживание пользователя на карте (но ивар местоположения все равно будет обновляться).
Если вы хотите продолжать следить за пользователем, но увеличить изображение только в первый раз, сделайте это вместо этого:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
location = newLocation.coordinate;
if (didZoomToUserLocation)
{
//just re-center map on user's location without changing zoom...
[mapView setCenterCoordinate:newLocation.coordinate animated:YES];
}
else
{
didZoomToUserLocation = YES;
MKCoordinateRegion region;
region.center = location;
MKCoordinateSpan span;
span.latitudeDelta = .005;
span.longitudeDelta = .005;
region.span = span;
[mapView setRegion:region animated:TRUE];
}
}
Кроме того, в вашем viewDidLoad вам не нужно вызывать insertSubview в MapView, если он создан в IB.
Комментарии:
1. Привет, большое спасибо за это, мне интересно, что вы имеете в виду в своем комментарии // просто переориентируйте карту на местоположение пользователя без изменения масштаба … ? кроме того, инициализация логических переменных на NO в viewdidload предотвратит масштабирование в первый раз, не так ли??
2. «Просто перенастроить центр» означает сохранить карту центрированной по местоположению пользователя, но не изменять масштаб. Например, если пользователь уменьшил масштаб карты, он сохранит этот уровень масштабирования, но карта будет центрирована по местоположению пользователя. Мы назвали bool did ZoomToUserLocation (на самом деле мы имеем в виду did-Auto-Zoom-To-User-Location), поэтому мы должны инициализировать значение NO, потому что мы не выполняли автоматическое масштабирование, пока не будет вызван didUpdateLocation. Если вы измените имя bool на needToDo AutoZoom, то вы инициализируете значение YES (и измените свою логику в didUpdateToLocation).
3. Привет, когда я тестирую это на устройстве, я вижу, что масштабирование очень высокое, я имею в виду, что увеличение при загрузке представления очень большое, какое значение я должен присвоить span, чтобы увеличить масштаб??
4. Значения диапазона указаны в градусах. Документы для MKCoordinateSpan объясняют, что это означает в милях / километрах. Больший диапазон означает, что видна большая область.
5. Привет, моя проблема в том, что у меня нет iPhone для тестирования приложения, но я бы спросил, например, что разумнее — .002 или .005, другими словами, когда мы говорим о видимости, .002 — это # looseness, чем .005 или наоборот??
Ответ №2:
Ваш код в didUpdateToLocation устанавливает диапазон фиксированного значения. Каждый раз, когда вызывается этот вызов делегата, он устанавливает масштаб на основе этих 0,005 интервалов.
Если вы просто поставите точку останова или войдете в функцию, вы увидите, что обычно она вызывается довольно часто.
Комментарии:
1. Привет, спасибо за ваш ответ, но как бы мне это исправить, мне нужно установить значение масштабирования при загрузке представления, и мне нужно отключить его, когда пользователь уменьшает масштаб??