2013-02-08 21 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; 
}