2012-08-06 54 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) 

    } 
}