多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### 程序概括: ###  1.对数据进行过滤查找。2.最上头要有一个SearchBar,对输入数据进行检索,点击SearchBar上的cancer按钮退出屏幕键盘并清除输入框内的数据。3.索引栏:在索引最上方添加一个扩大镜(UITableViewIndexSearch)。点击扩大镜的作用就是让SearchBar出现在屏幕最上方。 ### 程序的样子: ![](https://box.kancloud.cn/2016-06-12_575cce7ef3e4d.png) ![](https://box.kancloud.cn/2016-06-12_575cce7f3a2e3.png) ### 再罗嗦几句:此程序的数据存在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)。