【问题标题】:uisearchbar uisearchdisplaycontroller tableview subtitle erroruisearchbar uisearchdisplaycontroller tableview 字幕错误
【发布时间】:2012-09-19 11:36:37
【问题描述】:

我的表格视图搜索栏有点问题

我用数组 tableViewArray 创建了一个 tableview。
tableViewArray 由另一个数组的多行组成,该数组由 [text, distance] 组成。 一切正常。
现在我添加了一个 searchBar 和一个 searchdisplaycontroller,它们基于一个新的字符串数组(来自 tableViewArray 的“文本”对象)进行搜索。 我认为搜索应该只对文本可用,并且搜索方法是在其上实现的。

现在,当我得到搜索结果时,它看起来不错,并且搜索返回了预期的行。问题在于搜索 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);

【问题讨论】:

  • 您是否将 searchresults 数组中的对象复制到您的 tableview 数组中??
  • 我该怎么做? searchResults 数组仅由 tableview 数组的索引 0 组成。所以它根本不考虑索引 1(距离)。

标签: objective-c ios xcode searchbar searchdisplaycontroller


【解决方案1】:

如果我正确理解您的问题,您有 2 个单独的数组用作表格视图的数据源,我们称它们为 textArraydistanceArray

现在你根据搜索字符串过滤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];

现在您可以使用filteredTextArrayfilteredDistanceArray 作为搜索表视图的数据源。

或者,如果数组中的每个对象都是例如包含一行文本和距离的字典,则可以使用单个数组作为数据源。

更新:据我所知,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是过滤后的数组,每个item和tableViewArray中的item结构一样。

这简化了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];
}

【讨论】:

  • 您好,我使用相同的数组作为tableview 的数据源。但是这个数组是你提到的两个数组的组合。 tableview 数组的索引 0 来自 locationArray,索引 1 来自距离数组。我基本上在位置数组上进行搜索,在这种情况下是“searchitems”(位置数组的副本)。所以 tableViewArray 是(索引 0 位置,索引 1 距离)。在您编写的代码中,您在哪里定义实际搜索的内容? (我会同时尝试你的解决方案,我认为这几乎是我认为必须是答案)顺便说一句,谢谢:)
  • @B-Man:我的代码在数组textArray 中搜索searchText。 - 我还不明白你的阵列是如何工作的。如果您显示cellForRowAtIndexPath: 的代码,这可能会有所帮助。 - 或者您先尝试我的解决方案,如果您有更多问题,请回复……随您所愿。
  • @B-Man:请查看我的更新答案,希望对您有所帮助。否则欢迎你再问,但我可能不会在明天之前回复。
  • 感谢这位看起来很棒的人。我会调查一下,明天也会回复你:)祝你晚安:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-12
  • 2013-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多