(5) iphone 开发 在表视图(UITableView) 中利用UISearchBar实现数据的搜索,视图的多功能化

程序概括:

 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文件数据定义规则




  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值