Ios 在MKMapview上移动MKCircle并拖动MKMapview

Ios 在MKMapview上移动MKCircle并拖动MKMapview,ios,mkmapview,uipangesturerecognizer,mkoverlay,Ios,Mkmapview,Uipangesturerecognizer,Mkoverlay,我在MKMapView上有一个MKCircle。它是用户可以拖动的,但是如果用户拖动圆外的区域,则地图应该移动 - (IBAction)createPanGestureRecognizer:(id)sender { _mapView.scrollEnabled=NO; _panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector

我在MKMapView上有一个MKCircle。它是用户可以拖动的,但是如果用户拖动圆外的区域,则地图应该移动

- (IBAction)createPanGestureRecognizer:(id)sender
{
    _mapView.scrollEnabled=NO;
    _panRecognizer = [[UIPanGestureRecognizer alloc]
                      initWithTarget:self action:@selector(respondToPanGesture:)];
    [_mapView addGestureRecognizer:_panRecognizer];
}

-(void)respondToPanGesture:(UIPanGestureRecognizer*)sender {

    static CGPoint originalPoint;

    if (sender.state == UIGestureRecognizerStateBegan) {
        CGPoint point = [sender locationInView:_mapView];
        CLLocationCoordinate2D tapCoordinate = [_mapView convertPoint:point toCoordinateFromView:_mapView];

        CLLocation *tapLocation = [[CLLocation alloc] initWithLatitude:tapCoordinate.latitude longitude:tapCoordinate.longitude];

        CLLocationCoordinate2D originalCoordinate = [_circle coordinate];
        CLLocation *originalLocation = [[CLLocation alloc] initWithLatitude:originalCoordinate.latitude longitude:originalCoordinate.longitude];

        if ([tapLocation distanceFromLocation:originalLocation] > [_circle radius]) {
            _mapView.scrollEnabled=YES;
            _isAllowedToMove=NO;
        }
        else if ([tapLocation distanceFromLocation:originalLocation] < [_circle radius]) {
            originalPoint = [_mapView convertCoordinate:originalCoordinate toPointToView:sender.view];
            _isAllowedToMove=YES;
        }
    }

    if (sender.state == UIGestureRecognizerStateChanged) {
        if (_isAllowedToMove)
        {
            CGPoint translation = [sender translationInView:sender.view];
            CGPoint newPoint    = CGPointMake(originalPoint.x + translation.x, originalPoint.y + translation.y);

            CLLocationCoordinate2D newCoordinate = [_mapView convertPoint:newPoint toCoordinateFromView:sender.view];

            MKCircle *circle2 = [MKCircle circleWithCenterCoordinate:newCoordinate radius:[_circle radius]];
            [_mapView addOverlay:circle2];
            [_mapView removeOverlay:_circle];
            _circle = circle2;
        }
    }

    if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed || sender.state == UIGestureRecognizerStateCancelled) {
        _mapView.scrollEnabled=NO;
        _isAllowedToMove=NO;
    }
}
使地图可拖动,但需要另一个拖动手势才能启动。
如何在不丢失移动圆的能力的情况下完成此操作?

若要使其在用户开始在圆外拖动时可以拖动地图(若用户开始在圆内拖动时不拖动地图),请不要从一开始就禁用
滚动启用
,请保持打开状态(直到开始拖动,我们可以决定是否禁用)

为了使
滚动启用
最初处于启用状态(即让地图自行平移)并添加我们自己的手势识别器,我们需要使用手势识别器实现
应同时识别
并返回

更新的
createPangestureRecognitor:
如下所示:

- (IBAction)createPanGestureRecognizer:(id)sender
{
    //_mapView.scrollEnabled=NO;  // <-- do NOT disable scrolling here
    _panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(respondToPanGesture:)];
    _panRecognizer.delegate = self;  // <-- to implement shouldRecognize
    [_mapView addGestureRecognizer:_panRecognizer];
}

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}
最后,当手势结束时(以防万一),始终重新启用
scrollEnabled

当下一个手势开始时,如有必要,将重新禁用该手势:

if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed || sender.state == UIGestureRecognizerStateCancelled) {
    _mapView.scrollEnabled=YES;  // <-- enable instead of disable
    _isAllowedToMove=NO;
}
if(sender.state==UIgestureRecognitizerStateEnded | | | sender.state==UIgestureRecognitizerStateFailed | | sender.state==UIgestureRecognitizerStateCancelled){

_mapView.scrollEnabled=YES;//使用swift 4更新答案

包括一些更改:
panGesture.maximumnumnumberoftoffothes=1
以避免在平移手势时检测到收缩缩放 用于活动区域的屏幕点,可在其中启动平移手势

private func addPanGestureRecognizer(to map: MKMapView) {
    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(respondToPanGesture(_:)))
    panGesture.maximumNumberOfTouches = 1
    panGesture.delegate = self
    map.addGestureRecognizer(panGesture)
}

@objc private func respondToPanGesture(_ sender: UIPanGestureRecognizer) {
    guard let map = self.map else {
        return
    }

    let circlePoint = map.convert(startPoint, toPointTo: map) // circle center in View coordinate system

    switch sender.state {
    case .began:
        let point = sender.location(in: map)
        // Set touch radius in points (20), not meters to support different map zoom levels
        if point.radiusContainsPoint(radius: 20, point: circlePoint) {
            // set class property to store initial circle position before start dragging
            initialDragPoint = circlePoint
            map.isScrollEnabled = false
            isDragEnabled = true
        }
        else {
            map.isScrollEnabled = true
            isDragEnabled = false
        }
    case .changed:
        if isDragEnabled {
            let translation = sender.translation(in: map)
            let newPoint = CGPoint(x: initialDragPoint.x + translation.x, y: initialDragPoint.y + translation.y)
            let updatedCoordinate = map.convert(newPoint, toCoordinateFrom: map)
            let newOverlay = makeCircleOverlay(at: updatedCoordinate)
            map.remove(circleOverlay)
            map.add(newOverlay)
            circleOverlay = newOverlay
        }
    case .ended, .failed, .cancelled:
        map.isScrollEnabled = true
        isDragEnabled = false
    case .possible:
        break
    }
}

// MARK: - UIGestureRecognizerDelegate
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

谢谢。我用手势识别器实现了
应该同时识别,并将代码扭曲了几十次,但我忘记了一些简单的事情,比如
\u panRecognizer.delegate=self
;如果有人想使用代码,请不要忘了在@interface行的末尾添加
。要添加或删除手势记录,请我使用切换按钮。
if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed || sender.state == UIGestureRecognizerStateCancelled) {
    _mapView.scrollEnabled=YES;  // <-- enable instead of disable
    _isAllowedToMove=NO;
}
private func addPanGestureRecognizer(to map: MKMapView) {
    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(respondToPanGesture(_:)))
    panGesture.maximumNumberOfTouches = 1
    panGesture.delegate = self
    map.addGestureRecognizer(panGesture)
}

@objc private func respondToPanGesture(_ sender: UIPanGestureRecognizer) {
    guard let map = self.map else {
        return
    }

    let circlePoint = map.convert(startPoint, toPointTo: map) // circle center in View coordinate system

    switch sender.state {
    case .began:
        let point = sender.location(in: map)
        // Set touch radius in points (20), not meters to support different map zoom levels
        if point.radiusContainsPoint(radius: 20, point: circlePoint) {
            // set class property to store initial circle position before start dragging
            initialDragPoint = circlePoint
            map.isScrollEnabled = false
            isDragEnabled = true
        }
        else {
            map.isScrollEnabled = true
            isDragEnabled = false
        }
    case .changed:
        if isDragEnabled {
            let translation = sender.translation(in: map)
            let newPoint = CGPoint(x: initialDragPoint.x + translation.x, y: initialDragPoint.y + translation.y)
            let updatedCoordinate = map.convert(newPoint, toCoordinateFrom: map)
            let newOverlay = makeCircleOverlay(at: updatedCoordinate)
            map.remove(circleOverlay)
            map.add(newOverlay)
            circleOverlay = newOverlay
        }
    case .ended, .failed, .cancelled:
        map.isScrollEnabled = true
        isDragEnabled = false
    case .possible:
        break
    }
}

// MARK: - UIGestureRecognizerDelegate
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}