下午到打了几个小时的球,回来洗了个燥,觉得全身都很舒服,感觉体内一周的毒素全部排除体外,哈哈,还是得多运动运动,特别是我们这些做程序员的,进入正题:
1.创建一个Navigation—based—Application项目,这样Interface Builder中会自动生成一个Table View,然后将Search Bar拖放到表示图上,以我们要给表示图添加搜索功能,不要忘记将Search Bar的delegate连接到File‘s Owner项,然后将Search Bar与searchBar变量连接。
2.在Resources文件夹下创建一个Movies.plist文件,然后为该文件添加一些数据,如下图:
3.在.h头文件添加如下内容:
#import <UIKit/UIKit.h> @interface MyTableView : UITableViewController <UISearchBarDelegate>{ NSDictionary *movieTitles; NSArray *years; IBOutlet UISearchBar *searchBar; BOOL isSearchOn; BOOL canSelectRow; //下面两个是搜索用到的两个变量 NSMutableArray *listOfMovies; NSMutableArray *searchResult; } @property(nonatomic,retain) NSDictionary *movieTitles; @property(nonatomic,retain)NSArray *years; @property(nonatomic,retain)UISearchBar *searchBar; -(void)donSearching:(id)sender; -(void)searchMoviesTableView; @end
4.当加载View窗口时,首先定位属性列表并把这个列表加载到listOfMovies中,然后将所有的年份提取到years中,然后添加搜索条并初始化搜索条用到的数据:
//读取Movies.plist文件的内容到变量里面 - (void)viewDidLoad { NSString *path = [[NSBundle mainBundle]pathForResource:@"Movies" ofType:@"plist"]; NSDictionary *dic = [[NSDictionary alloc]initWithContentsOfFile:path]; self.movieTitles = dic; [dic release]; NSArray *array = [[self.movieTitles allKeys]sortedArrayUsingSelector:@selector(compare:)]; self.years = array; //下面两句是添加搜索条 self.tableView.tableHeaderView = searchBar; self.searchBar.autocorrectionType = UITextAutocorrectionTypeYes; //初始化listofmovies listOfMovies = [[NSMutableArray alloc]init]; for (NSString *year in years) { NSArray *movies = [movieTitles objectForKey:year]; for(NSString *title in movies){ [listOfMovies addObject:title]; } } searchResult = [[NSMutableArray alloc]init]; isSearchOn = NO; canSelectRow = YES; [super viewDidLoad]; }
5.在自动生成的方法numberOfSectionsInTableView中添加如下代码,表示告诉表示图一共分多少节:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { if (isSearchOn) { return 1;//如果正在搜索就只有一个section } else return [self.years count]; }
6.在自动生成的方法tableView:numberOfRowsInSection:中添加如下代码,表示告诉表视图每一节显示多少行:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (isSearchOn) { return [searchResult count]; }else{ // Return the number of rows in the section. NSString *year = [self.years objectAtIndex:section]; NSArray *movieSection = [self.movieTitles objectForKey:year]; return [movieSection count]; } }
7.在自动生成的方法tableView:cellForRowAtIndexPath:中添加如下代码,为每一行设值:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } if (isSearchOn) { NSString *cellValue = [searchResult objectAtIndex:indexPath.row]; cell.textLabel.text = cellValue; }else{ NSString *year = [self.years objectAtIndex:[indexPath section]];//得到当前行所在的section NSArray *movieSection = [self.movieTitles objectForKey:year]; cell.textLabel.text = [movieSection objectAtIndex:[indexPath row]]; cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; } //为每一行添加图片 UIImage *image = [UIImage imageNamed:@"apple.jpeg"]; cell.imageView.image = image; return cell; }
8.实现tableView:titleForHeaderInSection:方法,将得到的年份作为每一节的Header:
//设置每个section的标题 -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ NSString *year = [self.years objectAtIndex:section]; if (isSearchOn) { return nil; } else{ return year; } }
9.为表格添加索引,只需要实现sectionIndexTitlesForTableView:方法,该方法返回每一节的Header数组:
//添加索引 -(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{ if (isSearchOn) return nil; else return years; }
10.当用户点击搜索栏会促发searchBarTextDidBeginEditing:事件(UISearchBarDelegate协议中定义的一个方法,我们在.h头文件中实现了这个协议),在该方法中,向屏幕右上角添加一个Done按钮,当用户点击Done按钮时会调用doneSearching方法:
//搜索筐得到焦点后 -(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{ isSearchOn = YES; canSelectRow = NO; self.tableView.scrollEnabled = NO; //添加down按钮及其点击方法 self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donSearching:)]autorelease]; }
11.doneSearching方法使得搜索栏移除了First Responder状态,因而会隐藏键盘,同时,通过调用表视图的reloadData方法重新加载表视图:
//点击down按钮后 -(void)donSearching:(id)sender{ isSearchOn = NO; canSelectRow = YES; self.tableView.scrollEnabled = YES; self.navigationItem.rightBarButtonItem = nil; [searchBar resignFirstResponder]; [self.tableView reloadData]; }
12.当用户在搜索栏中输入时,输入的每个字符都会触发searchBar:textDidChange:事件,只要搜索栏中有一个字符,就会调用searchMoviesTableView方法:
//搜索筐里面的文字改变后 -(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ if ([searchText length]>0) { isSearchOn = YES; canSelectRow = YES; self.tableView.scrollEnabled = YES; [self searchMoviesTableView];//调用搜索方法 } else{ isSearchOn = NO; canSelectRow = NO; self.tableView.scrollEnabled = NO; } [self.tableView reloadData]; }
13.searchMoviesTableView方法会搜索listOfMovies数组,通过NSString类的rangeOfString:options:方法,使用特定的字符串对每个名称进行搜索,返回的结果是一个nsRange对象,如果长度大于0就表示有一个匹配结果,将它添加到searchResult书组中:
//自定义的搜索方法,得到搜索结果 -(void)searchMoviesTableView{ [searchResult removeAllObjects]; for (NSString *str in listOfMovies) { NSRange titleResultsRange = [str rangeOfString:searchBar.text options:NSCaseInsensitiveSearch]; if (titleResultsRange.length > 0) { [searchResult addObject:str]; } } }
14.当用户点击键盘上的Search按钮时,就会调用如下方法:
-(void) searchBarSearchButtonClicked:(UISearchBar *)searchBar{ [self searchMoviesTableView]; }
15.新建一个新的文件,该文件在后面定义,点击表格的某一行后就会调转到该页面去并将点击的那一样的名称传过去,要想做到这一点必须实现如下方法:
//点击table某一行跳转页面 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { MyTableViewOneMessage *mytm = [[MyTableViewOneMessage alloc]initWithNibName:@"MyTableViewOneMessage" bundle:nil]; NSString *year = [self.years objectAtIndex:[indexPath section]]; NSArray *movieSection = [self.movieTitles objectForKey:year]; NSString *movieTitle = [movieSection objectAtIndex:[indexPath row]]; NSString *message = [[NSString alloc]initWithFormat:@"%@",movieTitle]; mytm.message = message; [self.navigationController pushViewController:mytm animated:YES]; [mytm release]; }
16.新添加的页面很简单,主要用来测试表格的点击事件,导航然后显示传过来的字符串:
Interface Builder中添加两个lable,具体的就不详细了,很简单的,下面是这个界面的.h和.m文件:
#import <UIKit/UIKit.h> @interface MyTableViewOneMessage : UIViewController { IBOutlet UILabel *mylable; NSString *message; } @property(nonatomic,retain)UILabel *mylable; @property(nonatomic,retain)NSString *message; @end
#import "MyTableViewOneMessage.h" @implementation MyTableViewOneMessage @synthesize mylable; @synthesize message; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } -(void)viewDidAppear:(BOOL)animated{ self.mylable.text = message; } - (void)dealloc { [mylable release]; [message release]; [super dealloc]; } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewDidLoad { self.navigationItem.title = @"Tableview传过来的值"; [super viewDidLoad]; // Do any additional setup after loading the view from its nib. } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } @end