子视图和手势的手势iOS中的MKMapView-基本的iOS [英] Gestures to subviews & MKMapView in iOS - basic iOS

查看:96
本文介绍了子视图和手势的手势iOS中的MKMapView-基本的iOS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下设置:

 mainViewController
    OverlayView - UIView
    mapView - MKMapView

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

My OverlayView is shown over mapView and responds to UIPanGestureRecognizer

现在,因为OverlayView在MapView之上,所以我无法正常使用MapView的缩放功能.

Now because OverlayView is above MapView, I can't get the pinch to zoom functionality of MapView to work..

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

What do I have to do to get mapView to react to pinch and OverLayView to react to Pan (as it does now)?

我现在拥有的解决方案只是在mainViewController中实现pinch2zoom功能,以便它相应地缩放mapView,但是它比最初的Apple实现要平滑得多.

The solution I have now is just implementing the pinch2zoom functionality in the mainViewController so that it scales mapView accordingly, but it is way less smooth than the original Apple's implementation.

推荐答案

如果视图应该位于MKMapView的前面,并且地图在其下方移动时不会在屏幕上移动,则应实施正如您所描述的,它是地图视图前面(即顶部)的单独视图.但是,与其让该前视图处理手势并尝试以编程方式更改地图视图,不如将该前视图的userInteractionEnabled设置为NO(可以以编程方式或通过Interface Builder进行此操作).这样一来,后面的地图视图就可以接收触摸了.

If you have a view that is supposed to be in front of the MKMapView and not move on the screen as the map moves underneath it, you should implement it as you've described, as a separate view in front of (i.e. on top of) the map view. But rather than having this front view handle gestures and try to change the map view programmatically, you should just set the userInteractionEnabled to NO for this front view (you can do this programmatically or via Interface Builder). This will let the map view behind it receive the touches.

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

If you have some controls on that front view which need to accept user interaction, then go ahead and enable user interaction for those few controls, but make sure that the bulk of this front view is configured to not have userInteractionEnabled.

如果您希望叠加层随地图一起移动,则应将叠加层本身添加到MKMapView本身,而不是单独的视图中.参见位置感知编程指南中的"nofollow>在地图上显示叠加层.如果您使用MKMapView叠加层而不是单独的视图,则不会丢失任何内置的手势.

If you wanted an overlay that should move with the map, you should just add the overlay to the MKMapView, itself, not a separate view. See Displaying Overlays on a Map in the Location Awareness Programming Guide. If you use MKMapView overlays instead of a separate view, you don't lose any of the built-in gestures.

例如,如果将MKMapView设置为delegate作为视图控制器,则可以在iOS 7中编写rendererForOverlay(对于早期版本,则为viewForOverlay方法):

For example, if you set the delegate for your MKMapView to be your view controller, you can then write a rendererForOverlay in iOS 7 (or viewForOverlay method for earlier versions):

// 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;
}

这将处理多边形,圆形和直线.显然,例如,如果仅绘制多边形,则可以相应地简化上面的代码.

This handles polygons, circles, and lines. Clearly if you're only drawing polygons, for example, you could simplify the above code accordingly.

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

Once you do that, you can now add an overlay directly to the map. For example, this adds an overlay that is a rectangle of a certain size around a particular coordinate:

- (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;
}

这篇关于子视图和手势的手势iOS中的MKMapView-基本的iOS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆