Панель поиска не работает?

У меня есть файл SQL, где хранятся 5 различных типов данных. Я добавляю эти данные в словарь, указанный с помощью ключей. а затем я добавляю этот словарь в массив tableData в качестве источника данных для таблицы и searchBar. Но это не поиск ничего.

добавив код ниже

- (void)viewDidLoad {
[super viewDidLoad];


dataSource =[[NSMutableArray alloc] init];
tableData = [[NSMutableArray alloc]init];
searchedData = [[NSMutableArray alloc]init];


NSString *query = [NSString stringWithFormat:@"SELECT * FROM Vegetables"];

SQLite *sqlObj1 = [[SQLite alloc] initWithSQLFile:@"ShoppersWorld.sqlite"];
[sqlObj1 openDb];
[sqlObj1 readDb:query];

    //  [query release];
for (int i=0; i<[dataSource count]; i++) {
    NSLog(@"data:%@",[dataSource objectAtIndex:i]);
}

while ([sqlObj1 hasNextRow]) 
{

    NSString *name=[sqlObj1 getColumn:1 type:@"text"];
    NSString *price=[sqlObj1 getColumn:2 type:@"text"];
    NSString *quantity=[sqlObj1 getColumn:3 type:@"text"];
    NSString *unit=[sqlObj1 getColumn:4 type:@"text"];
    NSString *total=[sqlObj1 getColumn:5 type:@"text"]; 


    dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys: name,@"nameOfVegetables",
                                                                price,@"priceOfVegetables",
                                                                quantity,@"quantityOfVegetables",
                                                                unit,@"unitOfVegetables",
                                                                total,@"totalPriceOfVegetables",nil];


        //NSLog(@"results:%@ %@",dict);
    [dataSource addObject:dict];


}

[tableData  addObjectsFromArray:dataSource];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"Cell";

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

}

    // Set up the cell...
    // Configure the cell.


else {

    cell.productLbl.text= [NSString stringWithFormat:@"%@",[[tableData objectAtIndex:indexPath.row]objectForKey:@"nameOfVegetables"] ];     
    cell.bPriceLbl.text = [NSString stringWithFormat:@"Rs %d/Kg",
                                        [[[tableData objectAtIndex:indexPath.row] objectForKey:@"priceOfVegetables"] intValue]]; 

    cell.qtyLbl.text = [NSString stringWithFormat:@"QTY: %@ %@",[[tableData objectAtIndex:indexPath.row] 
                                                               objectForKey:@"quantityOfVegetables"],[[tableData objectAtIndex:indexPath.row] objectForKey:@"unitOfVegetables"]] ;

    cell.tPriceLbl.text = [NSString stringWithFormat:@"TOTAL: %@",[[tableData objectAtIndex:indexPath.row]
                                                                    objectForKey:@"totalPriceOfVegetables"]];

}
return cell;
}

#pragma поисковые операции

- (IBAction)search:(id)sender{

sBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0,40,320,30)];
sBar.delegate = self;
[self.view addSubview:sBar];

}

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{

    // only show the status bar’s cancel button while in edit mode
[sBar setShowsCancelButton:YES animated:YES];
sBar.autocorrectionType = UITextAutocorrectionTypeNo;
    // flush the previous search content
[tableData removeAllObjects];
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{

[sBar setShowsCancelButton:NO animated:YES];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{

    [tableData removeAllObjects];// remove all data that belongs to previous search
    if([searchText isEqualToString:@""] || searchText==nil){
        [tableview reloadData];
        return;

}
NSInteger counter = 0;
for(NSString *name in dataSource)

    for (int i = 0; i < [dataSource count]; i++)
    {
        NSMutableDictionary *temp = (NSMutableDictionary*) [dataSource objectAtIndex:i];
        NSString *name = [NSString stringWithFormat:@"%@", [temp valueForKey:@"nameOfVegetables"]];
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];      
        NSRange r = [name rangeOfString:searchText options:NSCaseInsensitiveSearch];        
        if(r.location != NSNotFound)            
        {           
            if(r.location== 0)//that is we are checking only the start of the names.                
            {               
                [tableData addObject:name];             
            }           
        }       
        counter++;      
        [pool release];
    }

[tableview reloadData];
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{

sBar.hidden= YES;
    // if a valid search was entered but the user wanted to cancel, bring back the main list content
[tableData removeAllObjects];
[tableData addObjectsFromArray:dataSource];
@try{
    [tableview reloadData];
}
@catch(NSException *e){
}
[sBar resignFirstResponder];
sBar.text = @"";
}

1 ответ

Решение

В методах делегата поиска вы манипулируете не с искомыми данными, а с массивом таблиц данных. Как следует из названия, в массиве seekData предполагается хранить отфильтрованные данные.

Кстати, ваш подход использовать sqlite для источника данных и поглощения всей базы данных в массив неверен. В cellForRowAtIndexPath читайте из базы данных sqlite только те данные, которые вам нужны в данный момент.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   // load from sqlite only data for this cell.
   // Use searchBar.text with sqlite's LIKE to filter data from database
   NSUInteger row = [indexPath row];
   static NSString *CellIdentifier = @"SignsCellIdentifier";
   UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:CellIdentifier];
   if (cell == nil) {                                       
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }
    NSString *sql = [NSString stringWithFormat:@"SELECT fieldNameFromTable FROM TableName WHERE FieldToLookForIn LIKE \"%%%@%%\" LIMIT 1 OFFSET %u", searchBar.text ? searchBar.text : @"", row];
    sqlite3_stmt *stmt;
    int res = sqlite3_prepare_v2(database, [sql UTF8String], -1, &stmt, NULL);
    if (res != SQLITE_OK) {
        NSLog(@"sqlite3_prepare_v2() failed"];
        return nil;
    }

    if (sqlite3_step(stmt) == SQLITE_ROW) {
        const unsigned char *name = sqlite3_column_text(stmt, 0);            
        cell.text = [NSString stringWithUTF8String:(const char*)name];
    }
    sqlite3_finalize(stmt);
return cell;
}


Как применить поиск в этом подходе? В textDidChange ничего не делать, кроме как вызвать [tableView reloadData]. А в cellForRowAtIndexPath загрузите данные с помощью sqlite LIKE, используя searchBar.text в качестве поискового запроса. Таким образом, reloadData будет загружать только отфильтрованные записи. searchBarSearchButtonClicked будет вызывать только resignFirstResponder своего вызывающего абонента, удаляя клавиатуру с экрана. Больше ничего не нужно делать, потому что поиск уже завершен. searchBarCancelButtonClicked установит для свойства text вызывающего его значение nil, вызовет перезагрузку данных и снова вызовет resignFirstResponder.

- (void)searchBarCancelButtonClicked:(UISearchBar *)s {
    s.text = nil;
    [tableView reloadData];
    [s resignFirstResponder];
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)s {
    // search is already done
    [s resignFirstResponder];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    [tableView reloadData];
}

NumberOfRowsInSection также должен запрашивать БД с тем же SELECT, что и в cellForRowAtIndexPath, но с SELECT COUNT. Написание этого метода станет вашей домашней работой)

Другие вопросы по тегам