2013-02-08 75 views
0

我有以下设置:手势在iOS系统子视图和的MKMapView - 基本的iOS

mainViewController 
    OverlayView - UIView 
    mapView - MKMapView 

我OverlayView的显示在MapView类和响应UIPanGestureRecognizer

现在因为OverlayView的是上面的MapView,我可以” t得到缩放功能的MapView的工作..

我该怎么做才能让mapView对捏和OverLayView作出反应,以响应潘(如现在)?

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

回答

0

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

如果您在该前视图上需要接受用户交互的某些控件,那么请继续并为这些少数控件启用用户交互,但请确保将此前视图的大部分配置为不具有userInteractionEnabled


如果你想应该与移动地图的覆盖,你应该只覆盖添加到MKMapView,本身不是一个独立的视图。请参阅位置感知编程指南中的Displaying Overlays on a Map如果使用MKMapView覆盖而不是单独的视图,则不会丢失任何内置手势。

例如,如果你设置了delegate为您MKMapView是你的视图控制器,然后你可以写在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; 
} 
+0

谢谢!虽然我需要覆盖使用用户触摸(像用户控制的指南针那样运动),但我没有弄清楚如何用MKPolygonView做动画,所以我去了自定义UIView。此外,覆盖在我的情况几乎是位置独立(这就像各种图形用户界面).. – Stpn 2013-02-08 23:40:01

+2

@Stpn啊,这很容易。如果您只将'userInteractionEnabled'设置为'NO',并且它会让用户交互传递到地图视图。请务必将此设置设置为“NO”,以表示您放置在地图上方的视图背景。 – Rob 2013-02-08 23:47:09

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