iOS地图注释问题

问题描述:

我有一个地图视图,上面有几个注释和一个搜索栏。在iOS 6中一切正常,但iOS 7中存在问题。在iOS 7中,当我选择一个针时,标题弹出,我可以点击信息按钮以转到该位置的详细视图。问题是,当我在iOS 7上搜索时,作为搜索结果的注释在注释周围出现黑色区域​​,我无法点击信息按钮。iOS地图注释问题

下面是选择引脚上搜索:

enter image description here

这里,它是寻找一个后:

enter image description here

这里是我的,当你搜索会发生什么代码:

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar 
{ 
    id<MKAnnotation> ann; 
    BOOL annotationFound = NO; 
    // NSRange titleRange = [annTitle rangeOfString:searchText options:NSCaseInsensitiveSearch]; 
    // NSRange subtitleRange = [annSubtitle rangeOfString:searchText options:NSCaseInsensitiveSearch]; 

    for (int i = 0; i < [marketLocations count]; i++) 
    { 
     for (ann in marketLocations) 
     { 
      NSString *annTitle = ann.title; 
      NSString *annSubtitle = ann.subtitle; 
      NSString *searchText = [searchBar text]; 
      NSRange titleRange = [annTitle rangeOfString:searchText options:NSCaseInsensitiveSearch]; 
      NSRange subtitleRange = [annSubtitle rangeOfString:searchText options:NSCaseInsensitiveSearch]; 
      CLLocationCoordinate2D annCoord; 
      annCoord.latitude = ann.coordinate.latitude; 
      annCoord.longitude = ann.coordinate.longitude; 

      // if ([ann.title isEqualToString:[searchBar text]]) 
      if (titleRange.location != NSNotFound) 
      { 
       MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(annCoord, 5000, 5000); 
       [worldView setRegion:region animated:YES]; 
       [worldView selectAnnotation:ann animated:YES]; 
       annotationFound = YES; 
      } 
      // else if ([ann.subtitle isEqualToString:[searchBar text]]) 
      else if (subtitleRange.location != NSNotFound) 
      { 
       MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(annCoord, 5000, 5000); 
       [worldView setRegion:region animated:YES]; 
       [worldView selectAnnotation:ann animated:YES]; 
       annotationFound = YES; 
      } 
     } 
    } 
    if (annotationFound == NO) 
    { 
     UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"" message:@"No Matches Found" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
     [av dismissWithClickedButtonIndex:0 animated:YES]; 
     [av show]; 
    } 

    [searchBar resignFirstResponder]; 
} 

有两个关于中所示的搜索码奇怪的事情,我相信他们都在帮助导致奇怪的显示问题:

  1. for循环穿过marketLocations阵列和内for循环通过marketLocations阵列。

    这种嵌套看起来并不必要,并且会导致搜索执行比您需要的更多的迭代。

    如果有100个注释,搜索将执行100 x 100次迭代(10,000)而不是100次(因为循环中没有break s)。也许你可能会注意到搜索时略有延迟,当有不仅仅是几个注释。

    它看起来像你只需要一个for循环。

  2. 当“匹配”注释被发现,代码调用setRegionselectAnnotation(它们都涉及更新到显示),然后继续与搜索循环。

    在已经调用selectAnnotation之后继续搜索更多匹配的注释是没有意义的,因为地图视图只允许单次注释在任何时候被“选中”(显示标注)。

    您应该break循环一旦匹配注释中发现或追踪“最佳匹配注释”和呼叫setRegionselectAnnotation搜索循环之后。


我相信迭代与多个,快速调用setRegionselectAnnotation相结合的数百(可能数以千计)的很紧的循环导致此显示问题。我能够用100个注释复制它。

为什么它只出现在iOS 7中是我无法回答的东西,但我怀疑iOS 6对此感到高兴(也没有显示它)。

所以我的建议是:

  1. 使用单一for环和,
  2. 假设你要停在第一个“匹配”,做break停止循环中调用selectAnnotation之后。

的代码可能是这个样子:

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar 
{ 
    id<MKAnnotation> ann; 
    BOOL annotationFound = NO; 

    // SINGLE for-loop... 
    for (ann in marketLocations) 
    { 
     NSString *annTitle = ann.title; 
     NSString *annSubtitle = ann.subtitle; 
     NSString *searchText = [searchBar text]; 
     NSRange titleRange = [annTitle rangeOfString:searchText options:NSCaseInsensitiveSearch]; 
     NSRange subtitleRange = [annSubtitle rangeOfString:searchText options:NSCaseInsensitiveSearch]; 
     CLLocationCoordinate2D annCoord; 
     annCoord.latitude = ann.coordinate.latitude; 
     annCoord.longitude = ann.coordinate.longitude; 

     if (titleRange.location != NSNotFound) 
     { 
      MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(annCoord, 5000, 5000); 
      [worldView setRegion:region animated:YES]; 
      [worldView selectAnnotation:ann animated:YES]; 
      annotationFound = YES; 
      break; // <-- STOP searching, exit the loop 
     } 
     else if (subtitleRange.location != NSNotFound) 
     { 
      MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(annCoord, 5000, 5000); 
      [worldView setRegion:region animated:YES]; 
      [worldView selectAnnotation:ann animated:YES]; 
      annotationFound = YES; 
      break; // <-- STOP searching, exit the loop 
     } 
    } 

    if (annotationFound == NO) 
    { 
     UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"" message:@"No Matches Found" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
     [av dismissWithClickedButtonIndex:0 animated:YES]; 
     [av show]; 
    } 

    [searchBar resignFirstResponder]; 
} 
+0

它看起来像这个问题时注解结果是最后一个只发生它找到一个匹配,因此是显示的那个。如果我在那里添加中断,问题不会显示出来。这个问题虽然是我的搜索结果,虽然技术上正确,但不是我想要的。例如,如果我搜索haney,那么我会得到chaney的注释,因为它首先得到它。 – raginggoat

+0

对,所以你必须先循环所有注释来找到“最佳匹配”,然后在循环之后调用selectAnnotation。 – Anna

+0

我不知道如何找到最佳匹配。 – raginggoat

其实我已经找到了一个非常简单的解决。取而代之的

NSRange titleRange = [annTitle rangeOfString:searchText options:NSCaseInsensitiveSearch];

我把它改成

NSRange titleRange = [annTitle rangeOfString:searchText];

并设置

searchBar.autocapitalizationType = UITextAutocapitalizationTypeWords;