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??
#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];??
- ??
- }??
//讀取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];??
- }??
- (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];??
- ????}??
- }??
- (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;??
- }??
- (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;??
- ????}??
- ????}??
//設置每個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;??
- }??
//添加索引
-(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];??
- }??
//搜索筐得到焦點后
-(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];??
- }??
//點擊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];??
- }??
//搜索筐里面的文字改變后
-(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];??
- ????????}??
- ????}??
- }??
//自定義的搜索方法,得到搜索結果
-(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];??
- }??
-(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];??
- }??
//點擊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 <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??
#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



