iOS: 在UITableView中实现搜索功能关键代码
最终效果图:

主界面:
- (void)viewDidLoad
{
[super viewDidLoad];
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, searchBarHeight)];
searchBar.delegate = self;
self.tableView.tableHeaderView = searchBar;
[searchBar release];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[DataController instance].filterContacts count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//NSLog(@"RootView:cellForRowAtIndexPath");
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
Contact *contact = [[DataController instance].filterContacts objectAtIndex:indexPath.row];
cell.textLabel.text = [contact.cardName toString];
//[contact release]; 不能释放
return cell;
}
搜索部分:
#pragma mark - Searching
- (void)updateSearchString:(NSString*)aSearchString
{
[searchString release];
searchString = [[NSString alloc]initWithString:aSearchString];
[[DataController instance] filterContactsWithLastName:searchString];
[self.tableView reloadData];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[searchBar setShowsCancelButton:YES animated:YES];
self.tableView.allowsSelection = NO;
self.tableView.scrollEnabled = NO;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[searchBar setShowsCancelButton:NO animated:YES];
[searchBar resignFirstResponder];
self.tableView.allowsSelection = YES;
self.tableView.scrollEnabled = YES;
searchBar.text=@"";
[self updateSearchString:searchBar.text];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
self.tableView.allowsSelection = YES;
self.tableView.scrollEnabled = YES;
[self updateSearchString:searchBar.text];
[searchBar resignFirstResponder]; //隐藏输入键盘
}
其中DataController是数据操作类
DataController.h
#import <Foundation/Foundation.h>
@class Contact;
@interface DataController : NSObject {
NSArray* contacts;
NSMutableArray *filterContacts;
}
@property (retain, nonatomic)NSArray* contacts;
@property (retain, nonatomic)NSMutableArray* filterContacts;
-(void)filterContactsWithLastName:(NSString*)lastName;
+(DataController*)instance;
@end
DataController.m
#import "DataController.h"
#import "Contact.h"
#import "CardName.h"
#import "XMLParser.h"
@implementation DataController
@synthesize contacts;
@synthesize filterContacts;
+(DataController*)instance
{
static DataController* instance = nil;
if (!instance) {
instance = [[DataController alloc]init];
}
return instance;
}
- (id)init {
NSLog(@"DataController:init");
self = [super init];
if (self) {
XMLParser *xmlParser = [[XMLParser alloc]init];
[xmlParser parse];
self.contacts = xmlParser.contacts;
self.filterContacts = [[NSMutableArray alloc] initWithArray: contacts];
[xmlParser release];
}
return self;
}
- (void)dealloc {
NSLog(@"DataController:dealloc");
[self.filterContacts release];
[self.contacts release];
[super dealloc];
}
-(void)filterContactsWithLastName:(NSString*)lastName
{
NSLog(@"filter by %@", lastName);
[self.filterContacts release];
self.filterContacts = [[NSMutableArray alloc] initWithArray: contacts];
if (lastName && [lastName length] > 0)
{
//Case and diacritic insensitive lookups, such as name contains[cd] "itroen"
NSString* predicateFormat = @"(cardName.firstName CONTAINS[cd] %@) OR (cardName.middleName CONTAINS[cd] %@) OR (cardName.lastName CONTAINS[cd] %@)";
NSPredicate *predicate = [NSPredicate predicateWithFormat: predicateFormat, lastName, lastName, lastName];
[self.filterContacts filterUsingPredicate:predicate];
//[predicateFormat release];
}
}
@end
曾在下一句折腾了差不多一天,原因是之前cardName的属性为first,而不是firstName, 可能first是关键字吧!
NSString* predicateFormat = @"(cardName.firstName CONTAINS[cd] %@) OR (cardName.middleName CONTAINS[cd] %@) OR (cardName.lastName CONTAINS[cd] %@)";
签名:删除冗余的代码最开心,找不到删除的代码最痛苦!
浙公网安备 33010602011771号