Хм, моя первоначальная идея состояла в том, чтобы использовать метод делегата
- (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture;
чтобы переместить камеру назад, когда ваш предел прокрутки достигнут. Используя это, ваше представление карты может временно превысить ваш предел (в зависимости от частоты вызова метода делегата), когда пользователь прокручивает до конца, но анимация вернется к желаемому пределу.
Мы можем углубиться в детали, если вы считаете, что этот подход вам подходит.
ОБНОВЛЕНИЕ:
Хорошо, на самом деле я понял, что вы должны использовать другой метод делегата:
- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position {
вместо этого, поскольку он дает вам постоянные обновления положения при движении. willMove
вызывается только один раз перед перемещением. В любом случае, идея состоит в том, что вы настраиваете свой вид карты и ограничения (граничную рамку), которая будет e/g рамкой вашего наложения. В качестве примера я только что создал область вокруг своего местоположения и разместил в ней начальную позицию камеры. Это настроено в методе viewDidLoad
.
Далее в методе didChangeCameraPosition
вы
- изменить положение маркера, чтобы вы могли видеть, куда вы сейчас указываете
- проверьте, прошли ли вы пределы широты / долготы, что означает, что вы прошли границы своего наложения, и переместите / анимируйте назад
Имейте в виду, что приведенный ниже код не проверяет, прошли ли вы через угол (широта и длина одновременно), тогда вы можете оказаться за пределами ограничений, но вы можете легко проверить это условие с помощью большего количества если.
Контроллер просмотра с настройкой карты и методами делегирования приведен ниже, и я загрузил полный проект здесь: https://www.dropbox.com/s/1a599wowvkumaa8/LimitingMap.tar.gz . Пожалуйста, не забудьте предоставить вам ключ API в делегате приложения, так как я удалил свой из кода.
Итак, контроллер представления выглядит следующим образом:
#import "ViewController.h"
#import <GoogleMaps/GoogleMaps.h>
@interface ViewController () <GMSMapViewDelegate> {
CLLocationCoordinate2D center, topLeft, topRight, bottomLeft, bottomRight;
double leftLong, rightLong, bottomLat, topLat;
GMSMarker *currentPosition;
}
@property (weak, nonatomic) IBOutlet GMSMapView *mapView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// GMSMapview itself is wired in storyboard, just set delegate
self.mapView.delegate = self;
// Lat/long limits (bounding box)
leftLong = 15.0;
rightLong = 16.0;
bottomLat = 45.0;
topLat = 46.0;
// center coordinate for map view and set it to mapview
center = CLLocationCoordinate2DMake(45.895064, 15.858220);
GMSCameraPosition *cameraPosition = [GMSCameraPosition cameraWithLatitude:center.latitude
longitude:center.longitude
zoom:10];
self.mapView.camera = cameraPosition;
// Current position, for displaying marker
currentPosition = [GMSMarker markerWithPosition:center];
currentPosition.map = self.mapView;
// coordinates based on coordinate limits for bounding box drawn as polyline
topLeft = CLLocationCoordinate2DMake(topLat, leftLong);
topRight = CLLocationCoordinate2DMake(topLat, rightLong);
bottomLeft = CLLocationCoordinate2DMake(bottomLat, leftLong);
bottomRight = CLLocationCoordinate2DMake(bottomLat, rightLong);
// Create visual bounding box with fat polyline
GMSMutablePath *path = [[GMSMutablePath alloc] init];
[path addCoordinate:topLeft];
[path addCoordinate:topRight];
[path addCoordinate:bottomRight];
[path addCoordinate:bottomLeft];
[path addCoordinate:topLeft];
GMSPolyline *polyLine = [GMSPolyline polylineWithPath:path];
polyLine.strokeWidth = 10.0;
polyLine.map = self.mapView;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Google Maps iOS SDK delegate methods
- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position {
// Reposition GMSMarker introduced in viewDidLoad to updated position
currentPosition.position = position.target;
// The interesting part - a non-elegant way to detect which limit was passed
// If each of lat/long limits is passed, map will move or animate to limiting position
if (position.target.latitude > topLat) { // If you scroll past upper latitude
// Create new campera position AT upper latitude and current longitude (and zoom)
GMSCameraPosition *goBackCamera = [GMSCameraPosition cameraWithLatitude:topLat
longitude:position.target.longitude
zoom:position.zoom];
// Now, you can go back without animation,
//self.mapView.camera = goBackCamera;
// or with animation, as you see fit.
[self.mapView animateToCameraPosition:goBackCamera];
}
if (position.target.latitude < bottomLat) {
GMSCameraPosition *goBackCamera = [GMSCameraPosition cameraWithLatitude:bottomLat
longitude:position.target.longitude
zoom:position.zoom];
//self.mapView.camera = goBackCamera;
[self.mapView animateToCameraPosition:goBackCamera];
}
if (position.target.longitude > rightLong) {
GMSCameraPosition *goBackCamera = [GMSCameraPosition cameraWithLatitude:position.target.latitude
longitude:rightLong
zoom:position.zoom];
//self.mapView.camera = goBackCamera;
[self.mapView animateToCameraPosition:goBackCamera];
}
if (position.target.longitude < leftLong) {
GMSCameraPosition *goBackCamera = [GMSCameraPosition cameraWithLatitude:position.target.latitude
longitude:leftLong
zoom:position.zoom];
//self.mapView.camera = goBackCamera;
[self.mapView animateToCameraPosition:goBackCamera];
}
}
@end
person
Vladimir Kolbas
schedule
18.01.2014