手势子视图和MKMapView在iOS – 基本的iOS

我有以下设置:

mainViewController OverlayView - UIView mapView - MKMapView 

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

现在,因为OverlayView是MapView以上,我不能得到缩放functionMapView的工作..

我必须做些什么才能让mapView对捏和OverLayView做出反应来对Pan进行反应(就像现在这样)?

我现在的解决scheme只是在mainViewController中实现了pinch2zoomfunction,以便相应地缩放mapView,但它不如原来的Apple实现那样stream畅。

如果你有一个视图应该在MKMapView前面,而不是在地图移动时在屏幕上移动,那么你应该像前面描述的那样实现它,作为一个单独的视图)地图视图。 但不是让这个前视图处理手势,并尝试以编程方式更改地图视图,只需将此前视图的userInteractionEnabled设置为NO (可以通过编程方式或通过Interface Builder来完成此操作)。 这将让地图后面的视图接收触摸。

如果您在该前视图上需要接受用户交互的某些控件,则继续为这些less数控件启用用户交互,但请确保userInteractionEnabled视图的大部分已configuration为不具有userInteractionEnabled


如果你想要一个覆盖层,应该与地图一起移动,你只需要将覆盖层添加到MKMapView本身,而不是单独的视图。 请参阅位置感知编程指南中的在地图上显示覆盖图 如果使用MKMapView叠加而不是单独的视图,则不会丢失任何内置手势。

例如,如果delegate您的MKMapViewdelegate设置为您的视图控制器,则可以在iOS 7中编写rendererForOverlay (或针对较早版本的viewForOverlay方法):

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

如果我要提出的build议可以起作用,或者如果是一个好的解决scheme,我现在不是现在,反正这是主意

将您的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; }