【问题标题】:Detecting when a user scrolls MKMapView a certain distance?检测用户何时滚动 MKMapView 一定距离?
【发布时间】:2013-05-23 23:43:57
【问题描述】:

我想确定用户是否滚动了超过一定百分比的地图,然后禁用地图从用户位置居中(类似于地图应用的工作方式)。

我不确定要使用哪些方法。

我认为创建一个矩形并查看该矩形是否包含当前中心点会很简单,但是我必须以 IOS 3 为目标,因此我无法使用许多较新的 Mapkit api。

我尝试过使用 CLLocation,并在当前地图中心和用户位置之间使用 distanceFrom,但我试图确定该距离是否是某个百分比。

【问题讨论】:

    标签: iphone mapkit


    【解决方案1】:

    我个人认为,当有人可以发布一段代码的 sn-p 而不是关于如何进行此操作的一般散文时,它会更有帮助。这是我想出的——粗略地写出来以更好地回答这个问题:

    在我的头文件中:

    #define SCROLL_UPDATE_DISTANCE          80.00
    

    在我看来(既是 CLLocationManagerDelegate、MKMapViewDelegate 的代表):

    // this method is called when the map region changes as a delegate of MKMapViewDelegate
    - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
    {
        NSLog(@"regionDidChangeAnimated");
        MKCoordinateRegion mapRegion;   
        // set the center of the map region to the now updated map view center
        mapRegion.center = mapView.centerCoordinate;
    
        mapRegion.span.latitudeDelta = 0.3; // you likely don't need these... just kinda hacked this out
        mapRegion.span.longitudeDelta = 0.3;
    
        // get the lat & lng of the map region
        double lat = mapRegion.center.latitude;
        double lng = mapRegion.center.longitude;
    
        // note: I have a variable I have saved called lastLocationCoordinate. It is of type
        // CLLocationCoordinate2D and I initially set it in the didUpdateUserLocation
        // delegate method. I also update it again when this function is called
        // so I always have the last mapRegion center point to compare the present one with 
        CLLocation *before = [[CLLocation alloc] initWithLatitude:lastLocationCoordinate.latitude longitude:lastLocationCoordinate.longitude];
        CLLocation *now = [[CLLocation alloc] initWithLatitude:lat longitude:lng];
    
        CLLocationDistance distance = ([before distanceFromLocation:now]) * 0.000621371192;
        [before release];
        [now release];
    
        NSLog(@"Scrolled distance: %@", [NSString stringWithFormat:@"%.02f", distance]);
    
        if( distance > SCROLL_UPDATE_DISTANCE )
        {
            // do something awesome
        }
    
        // resave the last location center for the next map move event
        lastLocationCoordinate.latitude = mapRegion.center.latitude;
        lastLocationCoordinate.longitude = mapRegion.center.longitude;
    
    }
    

    希望这能让您朝着正确的方向前进。

    distanceFromLocation 是 iOS 3.2 及更高版本。 initWithLatitude 是 iOS 2.0 及更高版本。 MKCoordinateRegion 是 iOS 3.0 及更高版本。 MKMapView centerCoordinate 是 iOS 3.0 及更高版本。

    另外,请随时跳入并纠正我犯错的地方。我正在自己解决所有这些问题-但到目前为止,这对我来说效果很好。

    希望这对某人有所帮助。

    【讨论】:

    • 你是对的。我应该已经发布了答案。如果您解释为什么在您的答案中使用常量:0.000621...,我会将其标记为已接受的答案。
    • 米到英里的换算(虽然有点草率,应该是某种常数)。
    【解决方案2】:

    第一课:不要在 SO 上深夜提问。

    第二课:您可以简单地通过从用户当前位置构造一个 CGPoint 和从 MapView 中心构造一个 CGPoint 来实现这一点。

    用两个点,计算距离,看看是否超过了某个阈值。

    您还可以在地图中心周围构造一个 CGRect,如果这样更容易,请检查 CGRectContainsPoint。

    - (BOOL) isUserPointInsideMapCenterRegion
    {
        CLLocation * ul = _mapView.userLocation.location;
    
        CGPoint userPoint = [_mapView convertCoordinate: ul.coordinate toPointToView: _mapView];
        CGPoint mapPoint = [_mapView convertCoordinate: _mapView.centerCoordinate toPointToView: _mapView];
    
        if (fabs(userPoint.x - mapPoint.x) > MAP_CENTER_RECTANGLE_SIZE || fabs(userPoint.y - mapPoint.y) > MAP_CENTER_RECTANGLE_SIZE)
        {
            return NO;
        }
    
        return YES;
    }
    

    【讨论】:

    • 我知道这是旧的,但它正是我在酷代码之后的样子!
    【解决方案3】:

    我意识到这个问题现在有点老了,但我觉得this other question 中描述的答案更健壮,因为委托方法可以因任何原因被触发。使用UIPanGestureRecognizer检测滚动意味着用户手动滚动了地图,它可以检查地图是否滚动了X个像素,而不是依赖米,这意味着用户滚动或多或少取决于缩放级别.

    https://stackoverflow.com/a/11675587/159758

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      • 2018-04-17
      • 1970-01-01
      • 2017-09-20
      • 1970-01-01
      • 2015-12-15
      • 1970-01-01
      相关资源
      最近更新 更多