我的搜索栏对于tableview有一点问题
我用数组tableViewArray创建了一个tableview
tableViewArray由另一个数组组成,包括[text,distance]。
一切都很好。
现在我添加了一个searchBar和一个searchdisplaycontroller,它基于一个新的字符串数组(来自tableViewArray的“text”对象)进行搜索。
我认为搜索应该只适用于文本,并且搜索方法就是在那里实现的。
现在,当我收到搜索结果时,它看起来不错,搜索会返回预期的行。问题在于搜索tableViews副标题。它显示tableViewArray的第1,2,3行的距离。
我需要它来将距离映射到搜索tableview行中显示的文本。 我想我需要为包含[文本距离]的搜索结果创建一个新的表视图数组。文本不是问题,因为它来自搜索结果,但我如何将新距离映射到旧距离?
我在搜索代理中使用的搜索方法是:
searchResults = [[NSArray alloc]init];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@",
searchText];
searchResults = [searchItems filteredArrayUsingPredicate:resultPredicate];
希望有人可以帮忙:)提前谢谢!
原始代码:
- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section
{
if (theTableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [tableViewArray count];
}
}
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle
reuseIdentifier: CellIdentifier] ;
if (theTableView == self.searchDisplayController.searchResultsTableView) {
} else {
cell = [theTableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
}
// Configure the cell...
// cell.textLabel.numberOfLines = 0;
// cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
if (theTableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [[[tableViewArray objectAtIndex:indexPath.row] objectAtIndex:0] subtitle];
}
cell.detailTextLabel.textColor = [UIColor redColor];
float blabla= [[[tableViewArray objectAtIndex:indexPath.row] objectAtIndex: 1] doubleValue];
if (blabla < 1000) {
cell.detailTextLabel.text = [NSString stringWithFormat:@"%.2f m",blabla];
} else {
cell.detailTextLabel.text = [NSString stringWithFormat:@"%.2f km",blabla/1000];
}
NSString *text = [[[tableViewArray objectAtIndex:indexPath.row] objectAtIndex:0] subtitle];
NSRange q8RangeValue = [text rangeOfString:@"Q8" options:NSCaseInsensitiveSearch];
NSRange okRangeValue = [text rangeOfString:@"OK" options:NSCaseInsensitiveSearch];
if (q8RangeValue.length >0 ) {
cell.imageView.image = [UIImage imageNamed:@"q8.png"];
} else if (okRangeValue.length >0 ) {
cell.imageView.image = [UIImage imageNamed:@"OK logo.png"];
} else {
cell.imageView.image = nil;
}
return cell;
}
我在哪里制作搜索阵列:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(@"didUpdateToLocation Location calculator distance array for the tableView");
NSMutableArray * distancesInReverseOrder = [[NSMutableArray alloc] init];
for (int i = 0; i<allAnnotations.count; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0] ;
CLLocationCoordinate2D annotationCoord = [[allAnnotations objectAtIndex:indexPath.row] coordinate];
CLLocation *location = [[CLLocation alloc] initWithLatitude:annotationCoord.latitude longitude:annotationCoord.longitude];
distanceToMe = [newLocation distanceFromLocation:location];
[distancesInReverseOrder insertObject:[NSNumber numberWithFloat: distanceToMe] atIndex:0];
}
distances = [[NSMutableArray alloc] initWithArray:[[distancesInReverseOrder reverseObjectEnumerator] allObjects]];
// Assuming you have your points on the map in an NSArray called
// allAnnotations and your distances in distances, create a
// new mutable array to hold both
tableViewArray = [[NSMutableArray alloc] init];
// Iterate over all of the points, and add a new element to the mutable
// array which is a new array containing a point and its distance
for (int i = 0; i < allAnnotations.count; i++) {
NSArray *newItem = [NSArray arrayWithObjects: [allAnnotations objectAtIndex: i], [distances objectAtIndex: i], nil];
[tableViewArray addObject: newItem];
}
// Now, sort the new array based upon the distance in the second element
// of each array (ie, the distance).
[tableViewArray sortUsingComparator: ^(id obj1, id obj2) {
NSNumber *dist1 = [obj1 objectAtIndex:1];
NSNumber *dist2 = [obj2 objectAtIndex:1];
return [dist1 compare:dist2];
}];
searchResults = [NSMutableArray arrayWithCapacity:[tableViewArray count]];
searchItems = [[NSMutableArray alloc] init];
for (int i = 0; i < allAnnotations.count; i++) {
NSArray *newItem = [NSArray arrayWithObjects: [[[tableViewArray objectAtIndex:i] objectAtIndex:0] subtitle], @"bla", nil];
[searchItems addObject: newItem];
}
/*
for (int i=0; i<tableViewArray.count; i++) {
[searchItems insertObject:[[[tableViewArray objectAtIndex:i] objectAtIndex:0] subtitle] atIndex:0];
}
*/
NSLog(@"searchitems count is %i", searchItems.count);
[tableView reloadData];
[locationManager stopUpdatingLocation];
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
/*
// Update the filtered array based on the search text and scope.
// Remove all objects from the filtered search array
[searchResults removeAllObjects];
// Filter the array using NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",searchText];
// searchResults = [NSMutableArray arrayWithArray:[[tableViewArray objectAtIndex:1] filteredArrayUsingPredicate:predicate]];
* /
/*
searchResults = [[NSArray alloc] init];
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:@"SELF contains[cd] %@",
searchText];
searchResults =[searchItems filteredArrayUsingPredicate:resultPredicate];
*/
// Create index set of all objects in textArray that contain searchText:
NSIndexSet *set = [searchItems indexesOfObjectsPassingTest:
^BOOL(NSString *text, NSUInteger idx, BOOL *stop) {
NSRange range = [text rangeOfString:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)];
return (range.location != NSNotFound);
}];
// Filter textArray:
filteredTextArray = [searchItems objectsAtIndexes:set];
// Filter distanceArray:
filteredDistanceArray = [distances objectsAtIndexes:set];
NSLog(@"filtered text array is %@", filteredTextArray);
NSLog(@"filtered distance array is %@",filteredDistanceArray);
答案 0 :(得分:2)
如果我正确理解您的问题,您有2个单独的数组用作表格视图的数据源,我们称之为textArray
和distanceArray
。
现在您根据搜索字符串过滤了textArray
,您需要对distanceArray
进行“对应”过滤。
执行此操作的一种方法是将filteredArrayUsingPredicate
替换为indexesOfObjectsPassingTest
,因为这会返回一组可应用于两个数组的匹配索引:
// Create index set of all objects in textArray that contain searchText:
NSIndexSet *set = [textArray indexesOfObjectsPassingTest:
^BOOL(NSString *text, NSUInteger idx, BOOL *stop) {
NSRange range = [text rangeOfString:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)];
return (range.location != NSNotFound);
}];
// Filter textArray:
filteredTextArray = [textArray objectsAtIndexes:set];
// Filter distanceArray:
filteredDistanceArray = [distanceArray objectsAtIndexes:set];
现在,您可以使用filteredTextArray
和filteredDistanceArray
作为搜索表视图的数据源。
或者,如果数组中的每个对象都是一个包含文本和一行距离的字典,则可以使用单个数组作为数据源。
更新:据我所知,tableViewArray
的每个项目都是一个包含2个项目的数组(一个用于文本,另一个用于距离)。
在这种情况下,我建议直接过滤tableViewArray
:
NSIndexSet *set = [tableViewArray indexesOfObjectsPassingTest:
^BOOL(NSArray *item, NSUInteger idx, BOOL *stop) {
NSString *subtitle = [[item objectAtIndex:0] subtitle];
NSRange range = [subtitle rangeOfString:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)];
return (range.location != NSNotFound);
}];
searchResults = [tableViewArray objectsAtIndexes:set];
现在searchResults
是已过滤的数组,每个项目的结构与tableViewArray
中的项目相同。
这简化了cellForRowAtIndexPath
中的内容,例如
if (theTableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [[[searchResults objectAtIndex:indexPath.row] objectAtIndex:0] subtitle];
distance = [[[searchResults objectAtIndex:indexPath.row] objectAtIndex: 1] doubleValue];
} else {
cell.textLabel.text = [[[tableViewArray objectAtIndex:indexPath.row] objectAtIndex:0] subtitle];
distance = [[[tableViewArray objectAtIndex:indexPath.row] objectAtIndex: 1] doubleValue];
}