MKMapView不会移动和缩放到搜索结果

时间:2014-07-18 10:49:14

标签: ios objective-c mkmapview mapkit mkannotation

我在我的MKMapView中实现搜索,但我遇到了两个问题:

  1. 当我执行搜索时,位置会显示在结果中,并且在我开始移动到目的地后,地图会移动到找到的位置 。当搜索结果超出视图范围时,会发生这种情况。如果它们位于地图视图范围内或附近它们就可以了。
  2. 它"啤酒花"始终从一个搜索结果到另一个到用户的位置。我不期待这样的行为。
  3. 我已经尝试了几件事,我想,问题在于:didAddAnnotationViews

    [self.locationManager stopUpdatingLocation];
    MKAnnotationView *annotationView = [views objectAtIndex:0];
    NSLog(@"_Here_ %@", [views description]);
    id<MKAnnotation> mp = [annotationView annotation];
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate], 250, 250);
    
    [mv setRegion:region animated:YES];
    [self.mapView selectAnnotation:mp animated:YES];
    

    虽然,我也认为问题出在didUpdateToLocation,所以我在第一个引脚丢弃后(通过搜索或点击)禁用更新:

    - (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation {
    
    double miles = 0.3;
    double scalingFactor =
    ABS( cos(2 * M_PI * newLocation.coordinate.latitude /360.0) );
    
    MKCoordinateSpan span;
    span.latitudeDelta = miles/69.0;
    span.longitudeDelta = miles/( scalingFactor*69.0 );
    
    MKCoordinateRegion region;
    region.span = span;
    region.center = newLocation.coordinate;
    
    [self.mapView setRegion:region animated:YES];
    self.mapView.showsUserLocation = YES;
    }
    

    最后,搜索方法:

    -(void)searchBarSearchButtonClicked:(UISearchBar *)theSearchBar
    {
    MKLocalSearchRequest *searchRequest = [[MKLocalSearchRequest alloc] init];
    [searchRequest setNaturalLanguageQuery:theSearchBar.text];
    searchRequest.region = MKCoordinateRegionMakeWithDistance(self.mapView.userLocation.coordinate, 1000, 1000);
    
    MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:searchRequest];
    [localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
        if (!error) {
            NSMutableArray *annotations = [NSMutableArray array];
    
            [response.mapItems enumerateObjectsUsingBlock:^(MKMapItem *item, NSUInteger idx, BOOL *stop) {
    
                for (id<MKAnnotation>annotation in self.mapView.annotations)
                {
                    if (annotation.coordinate.latitude == item.placemark.coordinate.latitude &&
                        annotation.coordinate.longitude == item.placemark.coordinate.longitude)
                    {
                        return;
                    }
                }
    
                MKPointAnnotation *addAnnotation = [[MKPointAnnotation alloc] init];
                addAnnotation.title = [item.placemark.addressDictionary objectForKey:@"Street"];
                addAnnotation.coordinate = item.placemark.coordinate;
    
                [annotations addObject:addAnnotation];
            }];
            for (id<MKAnnotation>annotation in self.mapView.annotations) {
                [self.mapView removeAnnotation:annotation];
            }
            [self.mapView addAnnotations:annotations];
    
        } else {
            NSLog(@"Search Request Error: %@", [error localizedDescription]);
        }
    }];
    
    //Hide the keyboard.
    [self.searchBar resignFirstResponder];
    }
    

    我的目标是创建一个MapView,用户可以通过点击或搜索来固定位置,显然,可以看到搜索结果。

1 个答案:

答案 0 :(得分:1)

对于第一个问题:

  

当我执行搜索时,位置会出现在结果中,地图会移动到   只有在我开始移动到目的地后找到的位置。这个   当搜索结果超出视图范围时发生。如果他们   在地图视图的内部或附近,它很好。

这是因为您正在将地图移动到didAddAnnotationViews委托方法中找到的注释(至少是第一个)。

但只有当注释位于可见区域时才会调用该委托方法。如果注释被添加到地图中但它不在可见区域(尚未),则viewForAnnotation不会被调用,因此didAddAnnotationViews不会被调用。

然后,当您手动移动地图时,添加的注释开始进入可见区域,然后调用委托方法,突然地图跳转到其中一个注释。

请勿在{{1​​}}委托方法中调用setRegion

有时,这样做也会导致didAddAnnotationViewsviewForAnnotation次调用无休止的循环,因为当区域发生变化时,会导致其他注释无法显示,因此之前没有,所以调用didAddAnnotationViews然后调用viewForAnnotation,依此类推。

相反,请在didAddAnnotationViews方法中致电addAnnotations:(或更好,只需致电showAnnotations:)后立即设置区域。

我还会从searchBarSearchButtonClicked:移除对stopUpdatingLocation的来电。如果您将地图didAddAnnotationViews设置为showsUserLocation,您可能根本不需要位置管理员。


对于第二问题:

  

它&#34;啤酒花&#34;从一个搜索结果到另一个搜索结果的所有时间   用户的位置。我不希望这样做。

部分原因还在于调用了YES中的setRegion,还因为didAddAnnotationViews中调用了setRegion

因此,出于第一个问题所描述的原因,两个代表方法和用户的手动动作相互争斗,地图最终跳来跳去。

请勿使用didUpdateToLocation方法致电setRegion(或通过在BOOL中跟踪,将其称为一次,无论您是否& #39;已经缩放到用户位置了。)

不影响行为,但在didUpdateToLocation中将showsUserLocation设置为YES并不合理。为什么不在didUpdateToLocation中设置它或在storyboard / xib中打开它?

此外,没有必要像这样手动计算区域范围(让MapKit为您工作更好)。只需将里程转换为米,然后拨打viewDidLoad