### 程序概括:
### ?1.對數據進行過濾查找。2.最上頭要有一個SearchBar,對輸入數據進行檢索,點擊SearchBar上的cancer按鈕退出屏幕鍵盤并清除輸入框內的數據。3.索引欄:在索引最上方添加一個擴大鏡(UITableViewIndexSearch)。點擊擴大鏡的作用就是讓SearchBar出現在屏幕最上方。
### 程序的樣子:


### 再羅嗦幾句:此程序的數據存在plist文件中,其中有一個值得注意的一點是:本程序利用了類別(category,在類外定義其方法而不使用其子類)來實現了字典的深層復制。
### 其余的就靠仔細閱讀了
### 具體細節代碼中注釋的也很詳細,直接上代碼:
### 1)NSDictionary的類別,深層復制
### MutableDeepCopy.h
~~~
#import <Foundation/Foundation.h>
@interface NSDictionary (MutableDeepCopy)
-(NSMutableDictionary*)mutableDeepCopy;
@end
~~~
### MutableDeepCopy.m
~~~
#import "MutableDeepCopy.h"
@implementation NSDictionary (MutableDeepCopy)
-(NSMutableDictionary*)mutableDeepCopy{
NSMutableDictionary *mudic=[[NSMutableDictionary alloc] initWithCapacity:[self count]];
//獲取字典里的所有鍵進行便利
for (id key in [self allKeys]) {
//這里用id的原因是此時并不知道value里是否還含有其他類型數據(字典,數組:非字符串)。
id value=[self valueForKey:key];
id tmpvalue=nil;
if ([value respondsToSelector:@selector(mutableDeepCopy)]) {
tmpvalue=[value mutableDeepCopy];
}else if ([value respondsToSelector:@selector(mutableCopy)]) {
tmpvalue=[value mutableCopy];
}
[mudic setValue:tmpvalue forKey:key];
}
return mudic;
}
@end
~~~
### 2)控制器.h
~~~
#import <UIKit/UIKit.h>
@interface iphone0408UITableViewSearchViewController : UIViewController <UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate> {
UITableView *MyUITableView;
UISearchBar *MySearchBar;
BOOL issearching;
}
@property (nonatomic,retain) NSDictionary *localresource;
@property (nonatomic,retain) NSMutableDictionary *Myresource;
@property (nonatomic ,retain) NSMutableArray * Mykey;
@property (nonatomic, strong) IBOutlet UISearchBar *MySearchBar;
@property (nonatomic, strong) IBOutlet UITableView *MyUITableView;
-(void)resetTableView;
-(void)SearchData: (NSString*) searchtext;
@end
~~~
### 控制器.m
~~~
#import "iphone0408UITableViewSearchViewController.h"
#import "MutableDeepCopy.h"
@implementation iphone0408UITableViewSearchViewController
@synthesize MySearchBar;
@synthesize MyUITableView;
@synthesize localresource;
@synthesize Myresource;
@synthesize Mykey;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark-
#pragma mark NO.2 Custom Method
/*此方法做了三件事 1.得到將字典數據copy成可變字典的數據。2.得到數據的可變類型的鍵(key)。3.在索引最上方加了一個小的擴大鏡(UITableViewIndexSearch),用于還原圖表初始位置。
*/
-(void)resetTableView{
//得到可變字典(數據)深層復制
NSMutableDictionary *Mdic=[self.localresource mutableDeepCopy];
//付給全局變量
self.Myresource=Mdic;
//這里就需要注意了:需要把擴大鏡(UITableViewIndexSearch)也加到Mykey里
NSMutableArray *key=[[NSMutableArray alloc] init];
//先向key里添加第一個值,保證其在第一的位置(保證擴大鏡在索引的最上頭)。
[key addObject:UITableViewIndexSearch];
[key addObjectsFromArray:[[self.Myresource allKeys] sortedArrayUsingSelector:@selector(compare:)]];
self.Mykey=key;
// [self.MyUITableView reloadData];
}
#pragma mark NO.6
/*搜索刪除不符合的值。先準備一個空的可變key容器用于儲存不符合的key,接下來創建兩個可變數組容器,一個用于存儲key所對應的值(數組),另一個為空,用于存儲需要移除的值。
*/
-(void)SearchData:(NSString *)searchtext{
//準備儲存要刪掉的key
NSMutableArray *removekey=[[NSMutableArray alloc] init];
for (NSString * key in self.Mykey) {
NSMutableArray *localarr=[self.Myresource valueForKey:key];
//準備存儲要刪掉的key里的數組
NSMutableArray *removearr=[[NSMutableArray alloc] init];
for (NSString * tmpvalue in localarr) {
if ([tmpvalue rangeOfString:searchtext options:NSCaseInsensitiveSearch].location==NSNotFound ) {
[removearr addObject:tmpvalue];
}
}
if ([localarr count] == [removearr count]) {
[removekey addObject:key];
}
//移除不符合的值
[localarr removeObjectsInArray:removearr];
}
//移除不符合的值(key所對應的值(整個數組))
[self.Mykey removeObjectsInArray:removekey];
//重新加載(刷新)。
[MyUITableView reloadData];
}
#pragma mark - View lifecycle
#pragma mark NO.1 run
- (void)viewDidLoad
{
NSString *path=[[NSBundle mainBundle] pathForResource:@"PropertySearchList" ofType:@"plist"];
NSDictionary *dic=[[NSDictionary alloc] initWithContentsOfFile:path];
self.localresource=dic;
//調用已經寫好的方法
[self resetTableView];
//將表視圖向上偏移(伸長)44.0 目的是將搜索欄(UISearchBar)蓋住
[self.MyUITableView setContentOffset:CGPointMake(0.0, 44.0) animated:NO];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setMyUITableView:nil];
[self setMySearchBar:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark-
#pragma mark NO.3 TableVeiw Data Source Method
/*
1.分區數。2.每個分區的行數。3.cell顯示。4.分區標題。5.索引
*/
//返回分區個數
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [self.Mykey count]>0?[Mykey count]:1;
}
//返回所在分區的行數
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if ([self.Mykey count]==0) {
return 0;
}
NSString *key=[self.Mykey objectAtIndex:section];
NSArray *arr=[self.Myresource valueForKey:key];
return [arr count];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSInteger row=[indexPath row];
NSInteger section=[indexPath section];
static NSString *MyTagName=@"DongStone";
UITableViewCell *cell=[MyUITableView dequeueReusableCellWithIdentifier:MyTagName];
if (cell==nil) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyTagName];
}
NSString *key=[self.Mykey objectAtIndex:section];
NSArray *arr=[self.Myresource valueForKey:key];
cell.textLabel.text=[arr objectAtIndex:row];
return cell;
}
//設置分區標題三種情況 1.屏幕顯示范圍內沒有分區。2.key的值正好等于下標為零的放大鏡查找(UITableViewIndexSearch)。3.正常返回數據分區標題。
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if ([Mykey count]==0) {
return nil;
}
//注意:此行代碼必須在此處,如果拿到上面,當key無值時,程序會crash,內存泄露。
NSString *key=[Mykey objectAtIndex:section];
if (key==UITableViewIndexSearch) {
return nil;
}
return key;
}
////索引,當issearching為YES時說明searchbar被點擊----->[ 索引 ] 被nil,隱藏
-(NSArray*)sectionIndexTitlesForTableView:(UITableView *)tableView{
if (issearching) {
return nil;
}
return self.Mykey;
}
#pragma mark-
#pragma mark NO.4 TableView Delegate Method
//點擊uitableview觸發此方法。
-(NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[MySearchBar resignFirstResponder];
MySearchBar.text=@"";
issearching=NO;
[MyUITableView reloadData];
return indexPath;
}
#pragma mark-
#pragma mark NO.5 Search Bar Delegate Method
//點擊search按鈕
//從UISearchBar輸入框中提取內容調用SearchData方法進行查找
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
NSString *mysearch=[searchBar text];
[self SearchData:mysearch];
}
//自動搜索
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
if ([searchText length]==0) {
[self resetTableView];
[MyUITableView reloadData];
return;
}
[self SearchData:searchText];
}
//點擊Cancle按鈕
//清除記錄退回屏幕鍵盤,返回初始狀態。顯示索引。
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
issearching=NO;
MySearchBar.text=@"";
//當重新輸入時,重新加載,此前就是落下了這一步,讓我很頭疼。
[self resetTableView];
[MyUITableView reloadData];
[searchBar resignFirstResponder];
}
//點擊輸入框時被觸發
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
issearching=YES;
[MyUITableView reloadData];
}
//點擊索引會調用此方法。點擊擴大鏡UITableViewIndexSearch讓searchbar出現(因為擴大鏡在執行resettableview方法時把其下標設為0,加入key的,所以執行if語句會進入)。
-(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{
NSString *key=[self.Mykey objectAtIndex:index];
if (key==UITableViewIndexSearch) {
[MyUITableView setContentOffset:CGPointZero animated:NO];
return NSNotFound;
}
return index;
}
@end
~~~
### 3) 創建plist文件方法 ?點擊連接:[(6) iphone 開發 從應用程序看UITableView的:分組,分區,索引,工作原理及其變換法則,plist文件數據定義規則](http://blog.csdn.net/dongstone/article/details/7428157)。
- 前言
- (1) iphone開發,自定義Window-based Application 模板及委托運行機制
- (2) iphone 開發 表視圖UITableView結構深層剖析
- (3) iphone 開發 從應用程序看UITableView的:分組,分區,索引,工作原理及其變換法則,plist文件數據定義規則
- (4) iphone 開發 自定義UITableViewCell的子類 ,輕松添加圖片文本信息等
- (5) iphone 開發 在表視圖(UITableView) 中利用UISearchBar實現數據的搜索,視圖的多功能化
- (6) iphone 開發 真正理解委托(delegate)與數據源(data source)
- (7)---01 iphone 開發 數據傳遞 NSNotification 通知機制演示
- (7)---02 iphone 開發 數據傳遞 : 頁面切換與數據的反向傳遞以及協議(protocol)作用的體現
- (8)---01 iphone 開發 大話分析導航欄NavigationController
- (9) iphone 開發 AppSettings , 系統setting與應用程序setting間的數據控制
- (10) iphone 開發 用戶點擊,觸摸和手勢識別 解析