### 程序概括:
### 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)。
- 前言
- (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 开发 用户点击,触摸和手势识别 解析