2012-08-06 77 views
21

scrollEnabled似乎是易碎的,一旦用戶開始在MKMapView捏。防止在MKMapView中滾動,同樣在縮放時

您仍然無法用一根手指滾動,但如果您在放大和縮小時用兩個手指滾動,則可以移動地圖。

我曾嘗試:

  • 子類化MKMapKit禁用它裏面的滾動視圖。
  • 執行 - mapView:regionWillChangeAnimated:執行中心。
  • 禁用scrollEnabled

但沒有運氣。

誰能告訴我一個肯定的方法,只能放大一個MKMapView,所以中心點始終停留在中間?

+2

我收到這樣做,但沒有處理它的方式不同。我禁用了與MKMapView的交互,並在其上方添加了捏手勢識別器。然後,我將捏合手勢轉換爲相應的縮放級別。所以幾乎在功能上自己捏合縮放。由於這不能直接回答你的問題,如果這對你來說是一個可行的選擇,我會在代碼中回答問題。 – random 2012-08-14 05:38:06

回答

29

您可以嘗試使用UIPinchGestureRecognizer自己處理的捏手勢:

首先設置scrollEnabledzoomEnabledNO,並創建了手勢識別:

UIPinchGestureRecognizer* recognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self 
                       action:@selector(handlePinch:)]; 
[self.mapView addGestureRecognizer:recognizer]; 

在識別處理調整根據MKCoordinateSpan縮放比例:

- (void)handlePinch:(UIPinchGestureRecognizer*)recognizer 
{ 
    static MKCoordinateRegion originalRegion; 
    if (recognizer.state == UIGestureRecognizerStateBegan) { 
     originalRegion = self.mapView.region; 
    }  

    double latdelta = originalRegion.span.latitudeDelta/recognizer.scale; 
    double londelta = originalRegion.span.longitudeDelta/recognizer.scale; 

    // TODO: set these constants to appropriate values to set max/min zoomscale 
    latdelta = MAX(MIN(latdelta, 80), 0.02); 
    londelta = MAX(MIN(londelta, 80), 0.02); 
    MKCoordinateSpan span = MKCoordinateSpanMake(latdelta, londelta); 

    [self.mapView setRegion:MKCoordinateRegionMake(originalRegion.center, span) animated:YES]; 
} 

This可能無法像Apple的實施一樣完美地工作,但它應該可以解決您的問題。

+1

我不認爲這個解決方案太棒了。與蘋果提供的默認縮放相比,它感覺非常笨重。例如,捏和屏幕更新之間存在滯後。 – 2015-07-19 21:54:25

+0

這根本不起作用。 – Haitao 2016-01-23 01:49:04

+0

更改動畫:是動畫:否 在最後一行 [self.mapView setRegion:MKCoordinateRegionMake(originalRegion.center,span)animated:YES]; ,工作順利。 – 2017-02-01 10:58:35

1

嘗試在地圖視圖的代理中實施–mapView:regionWillChangeAnimated:–mapView:regionDidChangeAnimated:,以便地圖總是以您的首選位置爲中心。

+0

試過...這沒有效果。 – 2012-08-09 08:56:48

1

我對這些答案都沒有太多的運氣。做我自己的捏只是衝突太多。我遇到的情況是,普通的縮放比我自己捏的時候縮小得更遠。

本來,我想爲樓主做這樣的事情:

- (void) mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated { 
    MKCoordinateRegion region = mapView.region; 
    //... 
    // adjust the region.center 
    //... 
    mapView.region = region; 
} 

我發現他就是那個沒有任何影響。我還通過NSLog發現,即使我以編程方式設置regioncenterCoordinate,該方法也會啓動。這導致了這樣一個問題:「如果DID工作無法完成,上面不會有這樣的問題嗎?「

所以我揣測和假設到現在,雖然用戶縮放/滾動/旋轉正在發生的MapView某種程度上抑制或忽略更改區域。關於仲裁的東西呈現綱領性調整無能爲力。

如果是這樣的那麼問題的關鍵是如何讓區域調整在regionDidChanged:通知之外,並且由於任何調整都會觸發另一個通知,因此重要的是它能夠確定何時不再調整,這導致我進行了以下實現(其中subject提供了我想停留在中間的中心座標):

- (void) recenterMap { 
    double latDiff = self.subject.coordinate.latitude self.mapView.centerCoordinate.latitude; 
    double lonDiff = self.subject.coordinate.longitude - self.mapView.centerCoordinate.longitude; 
    BOOL latIsDiff = ABS(latDiff) > 0.00001; 
    BOOL lonIsDiff = ABS(lonDiff) > 0.00001; 
    if (self.subject.isLocated && (lonIsDiff || latIsDiff)) { 
     [self.mapView setCenterCoordinate: self.subject.coordinate animated: YES]; 
    } 
} 

- (void) mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated { 
    if (self.isShowingMap) { 
     if (self.isInEdit) { 
      self.setLocationButton.hidden = NO; 
      self.mapEditPrompt.hidden = YES; 
     } 
     else { 
      if (self.subject.isLocated) { // dispatch outside so it will happen after the map view user events are done 
       dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^{ 
        [self recenterMap]; 
       }); 
      } 
     } 
    } 
} 

將其滑回的延遲時間可能會有所不同,但它確實工作得很好。並讓地圖互動在發生時保持Apple式。

1

我試過這個,它的工作原理。在regionWillChangeAnimated

var originalCenter: CLLocationCoordinate2D? 

然後,檢查此事件是由UIPinchGestureRecognizer造成的:

首先創建一個屬性

func mapView(mapView: MKMapView, regionWillChangeAnimated animated: Bool) { 
    let firstView = mapView.subviews.first 
    if let recognizer = firstView?.gestureRecognizers?.filter({ $0.state == .Began || $0.state == .Ended }).first as? UIPinchGestureRecognizer { 
     if recognizer.scale != 1.0 { 
      originalCenter = mapView.region.center 
     } 
    } 
} 

然後在regionDidChangeAnimated,回到原來的區域,如果捏合手勢引起區域變化:

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) { 
    if let center = originalCenter { 
     mapView.setRegion(MKCoordinateRegion(center: center, span: mapView.region.span), animated: true) 
     originalCenter = nil 
     return 
    } 
// your other code 
} 
1

Swift 3.0 @Paras Joshi版本回答https://stackoverflow.com/a/11954355/3754976

帶小動畫修復。

class MapViewZoomCenter: MKMapView { 

    var originalRegion: MKCoordinateRegion! 

    override func awakeFromNib() { 
     self.configureView() 
    } 

    func configureView() { 
     isZoomEnabled = false 
     self.registerZoomGesture() 
    } 

    ///Register zoom gesture 
    func registerZoomGesture() { 
     let recognizer = UIPinchGestureRecognizer(target: self, action:#selector(MapViewZoomCenter.handleMapPinch(recognizer:))) 
     self.addGestureRecognizer(recognizer) 
    } 

    ///Zoom in/out map 
    func handleMapPinch(recognizer: UIPinchGestureRecognizer) { 

     if (recognizer.state == .began) { 
      self.originalRegion = self.region; 
     } 

     var latdelta: Double = originalRegion.span.latitudeDelta/Double(recognizer.scale) 
     var londelta: Double = originalRegion.span.longitudeDelta/Double(recognizer.scale) 

     //set these constants to appropriate values to set max/min zoomscale 
     latdelta = max(min(latdelta, 80), 0.02); 
     londelta = max(min(londelta, 80), 0.02); 

     let span = MKCoordinateSpanMake(latdelta, londelta) 

     self.setRegion(MKCoordinateRegionMake(originalRegion.center, span), animated: false) 

    } 
}