0

私は次の設定をしています:

 mainViewController
    OverlayView - UIView
    mapView - MKMapView

私の OverlayView は mapView の上に表示され、UIPanGestureRecognizer に応答します

OverlayView が MapView の上にあるため、MapView のピンチ ツー ズーム機能を動作させることができません。

mapView をピンチに反応させ、OverLayView を Pan に反応させるにはどうすればよいですか (現在のように)。

私が今持っている解決策は、それに応じてmapViewをスケーリングするようにmainViewControllerにpinch2zoom機能を実装するだけですが、元のAppleの実装よりもはるかに滑らかではありません.

4

2 に答える 2

0

の前にあるはずのビューがありMKMapView、マップがその下を移動しても画面上で移動しない場合は、説明したように、の前にある別のビューとして (つまり、上に) 実装する必要があります。マップ ビュー。ただし、この正面図でジェスチャを処理し、マップ ビューをプログラムで変更しようとするのではなく、この正面図を に設定する必要userInteractionEnabledNOあります (これは、プログラムまたは Interface Builder を介して行うことができます)。これにより、その背後にあるマップ ビューがタッチを受け取れるようになります。

その正面図にユーザーの操作を受け入れる必要があるいくつかのコントロールがある場合は、それらのいくつかのコントロールに対してユーザー操作を有効にしますが、この正面図の大部分が を持たないように構成されていることを確認してuserInteractionEnabledください。


地図とともに移動するオーバーレイが必要な場合はMKMapView、別のビューではなく、オーバーレイを 自体に追加する必要があります。Location Awareness Programming Guideの「マップ上にオーバーレイを表示する」を参照してください。別のビューの代わりにオーバーレイを使用すると、組み込みのジェスチャが失われることはありません。MKMapView

たとえば、 をビュー コントローラーに設定するdelegateと、iOS 7 (または以前のバージョンのメソッド) でMKMapViewa を記述できます。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 に答える