Панель поиска не работает?
У меня есть файл 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. Написание этого метода станет вашей домашней работой)