如何防止'GMSMapView'无限水平滚动?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何防止'GMSMapView'无限水平滚动?相关的知识,希望对你有一定的参考价值。

如何通过无限水平滚动阻止ios 7上的“GMSMapView”?我正在使用'MKTileOverlay'和'kGMSTypeNone'来显示一个遍布世界各地的自定义图像。

(当用户向左滚动时,图像会再次重复。我希望滚动停在这里。)

答案

嗯,我最初的想法是使用委托方法

- (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture;

达到滚动限制时向后移动相机。使用此选项,当用户滚动到最后时,您的地图视图可能暂时超出您的限制(取决于委托方法调用的频率),但会动画回到您想要的限制。

如果您认为这种方法适合您,我们可以进一步了解详情。

更新:

好的,实际上我意识到你应该使用另一个委托方法:

- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position {

相反,它会在移动时为您提供持续的位置更新。 willMove在移动前只被召唤一次。无论如何,我们的想法是你设置地图视图和限制(边界框),这将是你的叠加层的e / g框。我刚刚在我的位置周围创建了一个区域作为示例,并在其中定位了初始摄像机位置。这是在viewDidLoad方法中设置的。

此外,在didChangeCameraPosition方法你

  1. 重新定位标记位置,以便您可以看到当前指向的位置
  2. 检查你是否通过了纬度/经度限制,这意味着你已经通过了覆盖边界并移动/动画回来了

请注意,下面的代码不会检查您是否已经通过了一个角落(同时为纬度和长度限制),然后您可能会结束限制,但您可以使用更多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
另一答案

你的代码总是不起作用,所以我改进了它(也是swift版本)

     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);

        }
    } 

以上是关于如何防止'GMSMapView'无限水平滚动?的主要内容,如果未能解决你的问题,请参考以下文章

防止sql注入方法 如何防止java中将MySQL的数据库验证密码加上 ' or '1'= '1 就可以出现万能密码 的PreparedStatement

jquery ajax如何防止多次提交

asp.net如何防止xss(脚本注入啊)

如何从内存中卸载 GMSMapView?

在asp中加入了防止sql注入代码 如何输入符号

将一个路径进行标准化的解析, 防止路径中连续出现多个‘/’,以及防止路径中出现'\', 防止路径结尾出现 '/'