2

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

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

4

2 回答 2

6

你的代码并不总是有效,所以我改进了它(也是快速版本)

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

        }
    } 
于 2016-07-01T01:57:21.027 回答
4

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

- (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 。请不要忘记在应用程序委托中为您提供 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
于 2014-01-18T13:43:15.320 回答