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

时间:2014-01-17 19:59:39

标签: google-maps-api-3 ios7 google-maps-sdk-ios gmsmapview

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

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

2 个答案:

答案 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方法

  1. 重新定位标记位置,以便您可以看到当前指向的位置
  2. 检查你是否通过了拉/长限制,这意味着你已经通过了叠加层的边界并移动/动画回来了
  3. 请注意,下面的代码不会检查您是否已经通过了一个角落(同时为纬度和长度限制),然后您可能会结束限制,但您可以使用更多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