如何通过无限水平滚动阻止IOS 7上的“GMSMapView”?我正在使用'MKTileOverlay'和'kGMSTypeNone'来显示一个遍布世界各地的自定义图像。
(当用户向左滚动时,图像会再次重复。我希望滚动停在这里。)
答案 0 :(得分:5)
你的代码总是不起作用,所以我改进了它(也是快速版本)
func mapView(mapView: GMSMapView, didChangeCameraPosition position: GMSCameraPosition) {
var latitude = position.target.latitude;
var longitude = position.target.longitude;
if (position.target.latitude > bounds.northEast.latitude) {
latitude = bounds.northEast.latitude;
}
if (position.target.latitude < bounds.southWest.latitude) {
latitude = bounds.southWest.latitude;
}
if (position.target.longitude > bounds.northEast.longitude) {
longitude = bounds.northEast.longitude;
}
if (position.target.longitude < bounds.southWest.longitude) {
longitude = bounds.southWest.longitude;
}
if (latitude != position.target.latitude || longitude != position.target.longitude) {
var l = CLLocationCoordinate2D();
l.latitude = latitude;
l.longitude = longitude;
mapView.animateToLocation(l);
}
}
答案 1 :(得分:4)
嗯,我最初的想法是使用委托方法
- (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture;
在达到滚动限制时向后移动相机。使用此选项,当用户滚动到最后时,您的地图视图可能暂时超出您的限制(取决于委托方法调用的频率),但会动画回到您想要的限制。
如果您认为这种方法适合您,我们可以进一步了解详情。
<强>更新强>
好的,实际上我意识到你应该使用另一个委托方法:
- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position {
相反,它会在移动时为您提供持续的位置更新。 willMove
仅在移动前被调用一次。无论如何,我们的想法是你设置地图视图和限制(边界框),这将是你的叠加层的e / g框。我刚刚在我的位置周围创建了一个区域作为示例,并在其中定位了初始摄像机位置。这是在viewDidLoad
方法中设置的。
此外,您使用didChangeCameraPosition
方法
请注意,下面的代码不会检查您是否已经通过了一个角落(同时为纬度和长度限制),然后您可能会结束限制,但您可以使用更多if来轻松检查该条件。
带有mapview设置和委托方法的Viewcontroller如下所示,我在这里上传了完整的项目:https://www.dropbox.com/s/1a599wowvkumaa8/LimitingMap.tar.gz。请不要忘记在app委托中为您提供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