我有一个地图视图,上面有几个注释和一个搜索栏。在iOS 6中一切正常但在iOS 7中存在问题。在iOS 7中,当我选择一个引脚时,标题会弹出,我可以点击信息按钮转到该位置的详细视图。问题是当我在iOS 7上搜索时,作为搜索结果的注释会在注释周围出现黑色区域,我无法点击信息按钮。
这是选择一个没有搜索的引脚:
这是在寻找一个之后:
以下是我搜索时会发生什么的代码:
- (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];
}
答案 0 :(得分:1)
显示的搜索代码有两个奇怪的地方,我相信它们都有助于引起奇怪的显示问题:
外部for
循环遍历marketLocations
数组,内部for
循环 遍历marketLocations
数组。
这种嵌套似乎不太必要,导致搜索执行的迭代次数超出了您的需要。
如果有100个注释,搜索将执行100 x 100次迭代(10,000)而不是100次(因为循环中没有break
s)。当有不止一些注释时,您可能会注意到搜索稍有延迟。
看起来您只需要一个for
循环。
找到“匹配”注释后,代码会调用setRegion
和selectAnnotation
(两者都涉及对显示的更新),然后 继续 与搜索循环。
在您已经调用selectAnnotation
之后继续搜索更多匹配的注释没有意义,因为地图视图只允许一次“选择”(显示标注)单个注释反正。
找到匹配的注释后,您应该break
循环,或者跟踪“最匹配的注释”并在之后调用setRegion
和selectAnnotation
搜索循环。
我相信数百次(可能是数千次)迭代的非常紧密的循环以及对setRegion
和selectAnnotation
的多次快速调用会导致此显示问题。我能用100个注释复制它。
为什么它只出现在iOS 7中是我无法回答的问题,但我怀疑iOS 6对此感到高兴(并且只是没有显示它)。
所以我的建议是:
for
循环,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];
}
答案 1 :(得分:0)
我实际上找到了一个非常简单的修复方法。而不是
NSRange titleRange = [annTitle rangeOfString:searchText options:NSCaseInsensitiveSearch];
我已将其更改为
NSRange titleRange = [annTitle rangeOfString:searchText];
并设置
searchBar.autocapitalizationType = UITextAutocapitalizationTypeWords;