0

我有以下设置:

 mainViewController
    OverlayView - UIView
    mapView - MKMapView

我的 OverlayView 显示在 mapView 上并响应 UIPanGestureRecognizer

现在因为 OverlayView 在 MapView 之上,我无法让 MapView 的缩放功能起作用..

我该怎么做才能让 mapView 对捏做出反应,让 OverLayView 对 Pan 做出反应(就像现在一样)?

我现在的解决方案只是在 mainViewController 中实现 pinch2zoom 功能,以便它相应地缩放 mapView,但它不如最初的 Apple 实现平滑。

4

2 回答 2

0

如果您有一个视图应该在前面MKMapView并且随着地图在其下方移动而不在屏幕上移动,您应该按照您的描述实现它,作为前面(即顶部)的单独视图地图视图。但是,与其让这个前视图处理手势并尝试以编程方式更改地图视图,不如只为这个前视图设置userInteractionEnabledNO您可以通过编程方式或通过 Interface Builder 执行此操作)。这将让它后面的地图视图接收到触摸。

如果您在该前视图上有一些需要接受用户交互的控件,则继续为这几个控件启用用户交互,但请确保该前视图的大部分配置为不具有userInteractionEnabled.


如果您想要一个应该随地图移动的叠加层,您应该只将叠加层添加到MKMapView, 本身,而不是单独的视图。请参阅Location Awareness Programming Guide中的在地图上显示叠加层。如果您使用覆盖而不是单独的视图,则不会丢失任何内置手势。MKMapView

例如,如果您将delegatefor your设置为您的视图控制器,则可以在 iOS 7 中MKMapView编写 a (或早期版本的方法):rendererForOverlayviewForOverlay

// for iOS7+; see `viewForOverlay` for earlier versions

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
    if ([overlay isKindOfClass:[MKPolygon class]])
    {
        MKPolygonRenderer *renderer = [[MKPolygonRenderer alloc] initWithPolygon:overlay];

        renderer.fillColor   = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
        renderer.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
        renderer.lineWidth   = 3;

        return renderer;
    }

    if ([overlay isKindOfClass:[MKCircle class]])
    {
        MKCircleRenderer *renderer = [[MKCircleRenderer alloc] initWithCircle:overlay];

        renderer.fillColor   = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
        renderer.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
        renderer.lineWidth   = 3;

        return renderer;
    }

    if ([overlay isKindOfClass:[MKPolyline class]])
    {
        MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];

        renderer.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
        renderer.lineWidth   = 3;

        return renderer;
    }

    return nil;
}

// for iOS versions prior to 7; see `rendererForOverlay` for iOS7 and later

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
    if ([overlay isKindOfClass:[MKPolygon class]])
    {
        MKPolygonView *overlayView = [[MKPolygonView alloc] initWithPolygon:overlay];

        overlayView.fillColor      = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
        overlayView.strokeColor    = [[UIColor blueColor] colorWithAlphaComponent:0.7];
        overlayView.lineWidth      = 3;

        return overlayView;
    }

    if ([overlay isKindOfClass:[MKCircle class]])
    {
        MKCircleView *overlayView = [[MKCircleView alloc] initWithCircle:overlay];

        overlayView.fillColor     = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
        overlayView.strokeColor   = [[UIColor blueColor] colorWithAlphaComponent:0.7];
        overlayView.lineWidth     = 3;

        return overlayView;
    }

    if ([overlay isKindOfClass:[MKPolyline class]])
    {
        MKPolylineView *overlayView = [[MKPolylineView alloc] initWithPolyline:overlay];

        overlayView.strokeColor     = [[UIColor blueColor] colorWithAlphaComponent:0.7];
        overlayView.lineWidth       = 3;

        return overlayView;
    }

    return nil;
}

这处理多边形、圆和线。显然,例如,如果您只绘制多边形,则可以相应地简化上述代码。

完成此操作后,您现在可以直接将叠加层添加到地图中。例如,这会添加一个覆盖,它是围绕特定坐标的特定大小的矩形:

- (void)addOverlayAround:(CLLocationCoordinate2D)originalCoordinate atDistance:(double)distanceKm
{
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(originalCoordinate, distanceKm * 1000.0 * 2.0, distanceKm * 1000 * 2.0);
    MKCoordinateSpan span = region.span;

    CLLocationCoordinate2D  points[4];
    points[0] = CLLocationCoordinate2DMake(originalCoordinate.latitude  + span.latitudeDelta / 2.0,
                                           originalCoordinate.longitude - span.longitudeDelta / 2.0);
    points[1] = CLLocationCoordinate2DMake(originalCoordinate.latitude  + span.latitudeDelta / 2.0 ,
                                           originalCoordinate.longitude + span.longitudeDelta / 2.0);
    points[2] = CLLocationCoordinate2DMake(originalCoordinate.latitude  - span.latitudeDelta / 2.0,
                                           originalCoordinate.longitude + span.longitudeDelta / 2.0);
    points[3] = CLLocationCoordinate2DMake(originalCoordinate.latitude  - span.latitudeDelta / 2.0,
                                           originalCoordinate.longitude - span.longitudeDelta / 2.0);

    MKPolygon* poly = [MKPolygon polygonWithCoordinates:points count:4];
    if ([self.mapView respondsToSelector:@selector(addOverlay:level:)])
        [self.mapView addOverlay:poly level:MKOverlayLevelAboveLabels];
    else
        [self.mapView addOverlay:poly];

//    // If you want to draw a circle around the coordinate, instead, you could do something like:
//
//    MKCircle *circle = [MKCircle circleWithCenterCoordinate:originalCoordinate radius:distanceKm * 1000.0 * sqrt(2.0)];
//    if ([self.mapView respondsToSelector:@selector(addOverlay:level:)])
//        [self.mapView addOverlay:circle level:MKOverlayLevelAboveLabels];
//    else
//        [self.mapView addOverlay:circle];

//    // if you want to draw some lines, you could do something like:
//  
//    MKPolyline *polyline = [MKPolyline polylineWithCoordinates:points count:4];
//    if ([self.mapView respondsToSelector:@selector(addOverlay:level:)])
//        [self.mapView addOverlay:polyline level:MKOverlayLevelAboveLabels];
//    else
//        [self.mapView addOverlay:polyline];

    self.mapView.delegate = self;
}
于 2013-02-08T23:28:24.973 回答
0

我现在实际上不知道我要提出的建议是否可行或者是否是一个好的解决方案,无论如何这就是想法

将您的 MainViewController 设置为手势识别器的委托

-(BOOL)gestureRecognizer:(UIGestureRecognizer*)gr shouldReceiveTouch:(UITouch*)touch{
    if([gr isKindOfClass:[UIPanGestureRecognizer class]])
        [mapView setUserInteractionEnabled:NO];
    else if([gr isKindOfClass:[UIPinchGestureRecognizer class]])
        [overlayView setUserInteractionEnabled:YES];
    return YES;
}
于 2013-02-08T23:39:16.890 回答