iOS地图注释问题

时间:2013-12-18 22:37:22

标签: ios objective-c ios7 annotations mkmapview

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

这是选择一个没有搜索的引脚:

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];
}

2 个答案:

答案 0 :(得分:1)

显示的搜索代码有两个奇怪的地方,我相信它们都有助于引起奇怪的显示问题:

  1. 外部for循环遍历marketLocations数组,内部for循环 遍历marketLocations数组。

    这种嵌套似乎不太必要,导致搜索执行的迭代次数超出了您的需要。

    如果有100个注释,搜索将执行100 x 100次迭代(10,000)而不是100次(因为循环中没有break s)。当有不止一些注释时,您可能会注意到搜索稍有延迟。

    看起来您只需要一个for循环。

  2. 找到“匹配”注释后,代码会调用setRegionselectAnnotation(两者都涉及对显示的更新),然后 继续 与搜索循环。

    在您已经调用selectAnnotation之后继续搜索更多匹配的注释没有意义,因为地图视图只允许一次“选择”(显示标注)单个注释反正。

    找到匹配的注释后,您应该break循环,或者跟踪“最匹配的注释”并在之后调用setRegionselectAnnotation 搜索循环。


  3. 我相信数百次(可能是数千次)迭代的非常紧密的循环以及对setRegionselectAnnotation的多次快速调用会导致此显示问题。我能用100个注释复制它。

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

    所以我的建议是:

    1. 使用单个for循环,
    2. 假设您想要停在第一个“匹配”,请break在调用selectAnnotation后立即停止循环。
    3. 代码可能如下所示:

      - (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];
      }
      

答案 1 :(得分:0)

我实际上找到了一个非常简单的修复方法。而不是

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

我已将其更改为

NSRange titleRange = [annTitle rangeOfString:searchText];

并设置

searchBar.autocapitalizationType = UITextAutocapitalizationTypeWords;