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

Ios MKMapView不会移动和缩放搜索结果,ios,objective-c,mkmapview,mapkit,mkannotation,Ios,Objective C,Mkmapview,Mapkit,Mkannotation,我正在MKMapView中实现搜索,我面临两个问题: 执行搜索时,结果中会显示位置,只有在我开始移动到目标位置后,地图才会移动到找到的位置。当搜索结果超出视图边界时,就会发生这种情况。如果它们在地图视图边界内或附近,则可以 它总是从一个搜索结果“跳跃”到另一个搜索结果或用户的位置。我不指望它会有这样的行为 我尝试了几种方法,我想问题出在:didAddAnnotationViews: [self.locationManager stopUpdatingLocation]; MKAnnotati

我正在MKMapView中实现搜索,我面临两个问题:

  • 执行搜索时,结果中会显示位置,只有在我开始移动到目标位置后,地图才会移动到找到的位置。当搜索结果超出视图边界时,就会发生这种情况。如果它们在地图视图边界内或附近,则可以
  • 它总是从一个搜索结果“跳跃”到另一个搜索结果或用户的位置。我不指望它会有这样的行为 我尝试了几种方法,我想问题出在:
    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];
    
    最后,搜索方法:

    -(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];
    }
    
    -(无效)搜索栏搜索按钮点击:(ui搜索栏*)搜索栏
    {
    MKLocalSearchRequest*searchRequest=[[MKLocalSearchRequest alloc]init];
    [SearchRequestSetNaturalLanguageQuery:theSearchBar.text];
    searchRequest.region=mkcoordinaeregionmakewithdistance(self.mapView.userLocation.coordinate,10001000);
    MKLocalSearch*localSearch=[[MKLocalSearch alloc]initWithRequest:searchRequest];
    [localSearch startWithCompletionHandler:^(MKLocalSearchResponse*响应,NSError*错误){
    如果(!错误){
    NSMutableArray*注释=[NSMutableArray];
    [response.mapItems enumerateObjectsUsingBlock:^(MKMapItem*项,整数idx,布尔*停止){
    for(self.mapView.annotations中的idannotation)
    {
    if(annotation.coordinate.latitude==item.placemark.coordinate.latitude&&
    annotation.coordinate.longitude==item.placemark.coordinate.longitude)
    {
    返回;
    }
    }
    MKPointAnnotation*addAnnotation=[[MKPointAnnotation alloc]init];
    addAnnotation.title=[item.placemark.addressDictionary objectForKey:@“Street”];
    addAnnotation.coordinate=item.placemark.coordinate;
    [注释addObject:addAnnotation];
    }];
    for(self.mapView.annotations中的idannotation){
    [self.mapView removeAnnotation:annotation];
    }
    [self.mapView addAnnotations:annotations];
    }否则{
    NSLog(@“搜索请求错误:%@,[Error localizedDescription]);
    }
    }];
    //隐藏键盘。
    [self.searchBar辞职FirstResponder];
    }
    

    我的目标是创建一个地图视图,用户可以点击或通过搜索锁定位置,显然,可以看到搜索结果

    对于第一个问题:

    当我执行搜索时,结果中会显示位置并将地图移动到 只有在我开始移动到目的地后才能找到位置。这 当搜索结果超出视图边界时发生。如果他们 在地图视图范围内或附近,没有问题

    这是因为您正在将映射移动到
    didAddAnnotationViews
    delegate方法中找到的注释(至少是第一个注释)

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

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

    不要在
    didAddAnnotationViews
    delegate方法内调用
    setRegion

    有时,这样做也会导致
    viewForAnnotation
    didAddAnnotationViews
    调用的无休止循环,因为当区域发生更改时,它会导致以前没有的其他注释进入视图,因此调用
    viewForAnnotation
    ,然后调用
    didAddAnnotationViews
    ,等等

    相反,在调用
    searchBarSearchButtonClicked:
    方法中的
    addAnnotations:
    (或者更好,只需调用
    showAnnotations:
    )后设置区域。

    我还将从
    didAddAnnotationViews
    中删除对
    stopUpdateLocation
    的调用。如果将地图的
    showsUserLocation
    设置为
    YES
    ,则可能根本不需要位置管理器


    对于第二个问题:

    它总是从一个搜索结果“跳跃”到另一个或另一个搜索结果 用户的位置。我不指望它会有这样的行为

    这部分也是由于在
    didAddAnnotationViews
    中调用
    setRegion
    ,但也因为在
    didaddupdatetolocation
    中调用了
    setRegion

    因此,由于第一个问题所述的原因,两个委托方法和用户的手动移动相互冲突,地图最终会四处跳跃

    不要在
    didUpdateToLocation
    方法中调用
    setRegion
    (或者,通过在BOOL中跟踪是否已缩放到用户位置来调用它一次)

    不影响行为,但在
    didUpdateLocation
    中将
    showsUserLocation
    设置为
    YES
    没有意义。为什么不在
    viewDidLoad
    中设置它,或者在故事板/xib中打开它


    此外,不需要像那样手动计算区域跨度(最好让MapKit为您完成这项工作)。只需将英里数转换为米,然后调用
    MKCoordinateRegionMakeWithDistance

    ,您可以将selectAnnotation保留在该委托方法中,如果它对您有效的话。目前显示的代码应该没有问题。
    -(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];
    }