最终效果图:
主界面:
- (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] %@)";