UITableView 分组显示数据与搜索,数据源plist [xcode 4.4.1]


本篇学习目标:

1. 学习使用读取plist

2. UITableView 分组显示数据

3. UITableView 加上搜索功能

 

不‘费’话,直接跟我一起来,进行如下操作:

 

1. 创建项目,在此略过,可以参考前篇文章,在此只显示一个项目的图:

 

2. 添加plist 文件

 PS: plist文件是什么呢? 它全名是:Property List,属性列表文件,它是一种用来存储串行化后的对象的文件。属性列表文件的扩展名为.plist,因此通常被称为plist文件。文件是xml格式 的。Plist文件通常用于储存用户设置,也可以用于存储捆绑的信息。

 

data.plist 文件图片如下:

 

查看源代码,如下

View Code
<? xml version="1.0" encoding="UTF-8" ?>
<! DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
< plist  version ="1.0" >
< dict >
     < key >1992 </ key >
     < array >
         < string >漫画威龙 </ string >
         < string >家有喜事 </ string >
         < string >逃学威龙2 </ string >
         < string >审死官 </ string >
         < string >鹿鼎记 </ string >
         < string >鹿鼎记2神龙教 </ string >
         < string >武状元苏乞儿 </ string >
     </ array >
     < key >1993 </ key >
     < array >
         < string >唐伯虎点秋香 </ string >
         < string >逃学威龙3龙过鸡年 </ string >
         < string >济公 </ string >
     </ array >
     < key >1994 </ key >
     < array >
         < string >破坏之王 </ string >
         < string >九品芝麻官 </ string >
         < string >国产凌凌漆 </ string >
     </ array >
     < key >1995 </ key >
     < array >
         < string >大话西游之月光宝盒 </ string >
         < string >回魂夜 </ string >
         < string >百变星君 </ string >
     </ array >
     < key >1996 </ key >
     < array >
         < string >大内密探零零发 </ string >
         < string >食神 </ string >
     </ array >
     < key >1997 </ key >
     < array >
         < string >97家有喜事 </ string >
         < string >算死草 </ string >
     </ array >
     < key >1998 </ key >
     < array >
         < string >行运一条龙 </ string >
     </ array >
     < key >1999 </ key >
     < array >
         < string >喜剧之王 </ string >
         < string >千王之王2000 </ string >
     </ array >
     < key >2000年以后 </ key >
     < array >
         < string >少林足球 </ string >
         < string >功夫 </ string >
         < string >长江七号 </ string >
     </ array >
     < key >1991 </ key >
     < array >
         < string >整蛊专家 </ string >
         < string >龙的传人 </ string >
         < string >新精武门1991 </ string >
         < string >逃学威龙 </ string >
         < string >赌侠2上海滩赌圣 </ string >
         < string >情圣 </ string >
     </ array >
</ dict >
</ plist >

 

3. 删除默认的ViewController,添加TableViewController(如果不清楚,请查看前篇文章)。

属性设置如下:

  • Style: 显示风格,上篇我们使用是基本的Basic,这里我们使用Subtitle,简单的讲,就是标题与字幕的显示。
  • Identifier: cell 的身份ID,这个是必须设置,我们这里设置成MovieCell
  • Accessory: 详细内容时的图标,我们这里设置成Detail Disclosure


 

4. 添加myDataViewController类,继承于UITableViewController,先修改 myDataViewController.h 文件

//
//   myDataViewController.h
//   listMovieGroup
//
//   Created by tony on 12-8-31.
//   Copyright (c) 2012年 chinapcc.com. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface myDataViewController : UITableViewController
{
     //  电影标题数据字典
    NSDictionary *movieTitles;
    
     //  年份的数组
    NSArray *years;
}

//  属性:电影标题数据字典
@property (nonatomic,retain) NSDictionary *movieTitles;

//  属性:年份的数组
@property (nonatomic,retain) NSArray *years;

@end

 

 

5. 修改 myDataViewController.m 文件

添加属性与加载时的代码:

@synthesize years;
@synthesize movieTitles;

- ( void)viewDidLoad
{
     //  获取plist资源文件地址
    NSString *path = [[NSBundle mainBundle] pathForResource: @" data " ofType: @" plist "];
    
     //  这是写入日记,为了调试,不是必须的
    NSLog( @" 资源文件路径: %@ ",path);
    
     //  根据文件路径获取字典内容
    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
    self.movieTitles = dict;
    
     //  根据字典,获得年份的数组
    NSArray *array = [[movieTitles allKeys] sortedArrayUsingSelector:@selector(compare:)];
    self.years = array;
    
     //  原来应该有如下两句,xcode 4.2以后,启用ARC之后,就不需要了
    
// [dict release];
    
// [array release];
    
    [super viewDidLoad];
}

- ( void)viewDidUnload
{
    self.movieTitles = nil;
    self.years = nil;
    [super viewDidUnload];
}

 

 6. 绑定数据源


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
     //  返回节点数,就是显示几个组,我们这里是按年份显示数据
     return [years count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     //  获取当前节点的年份
    NSString *year = [years objectAtIndex:section];
    
     //  根据节点的年份,获取字节点的数组
    NSArray *movieSection = [movieTitles objectForKey:year];
    
     //  返回当前字节的数量
     return [movieSection count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString *CellIdentifier =  @" MovieCell ";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
     //  获取节点的年份
    NSString *year = [years objectAtIndex:[indexPath section]];
    
     //  获取年份内所有电影数组
    NSArray *movie = [movieTitles objectForKey:year];
    
     //  根据数组获取电影的标题
    cell.textLabel.text = [movie objectAtIndex:[indexPath row]];
    cell.detailTextLabel.text =  @" 主演:周星驰 ";
    
     return cell;
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
     //  获取年份
    NSString   *year = [years objectAtIndex:section];
     return  year;
}

7. 不要忘记以下两个地方需要设置一下:

设置显示分组风格:

 

设置与控制器绑定:

 

 

8. 恭喜你完成,可以看一看效果


 

9. 结束了吗?还没有,还要有一个搜索,接下来吧。。。添加一个搜索框

 

 

10. 修改 myDataViewController.h 文件

View Code
//
//   myDataViewController.h
//   listMovieGroup
//
//   Created by tony on 12-8-31.
//   Copyright (c) 2012年 chinapcc.com. All rights reserved.
//

#import <UIKit/UIKit.h>

//  这里要实现一个委托 UISearchBarDelegate 
@interface myDataViewController : 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) searchMoviesTableView;

@end

 

11. 修改 myDataViewController.m 文件 注解在代码中,请大家仔细看清楚

View Code
//
//   myDataViewController.m
//   listMovieGroup
//
//   Created by tony on 12-8-31.
//   Copyright (c) 2012年 chinapcc.com. All rights reserved.
//

#import  " myDataViewController.h "

@interface myDataViewController ()

@end

@implementation myDataViewController

@synthesize years;
@synthesize movieTitles;
@synthesize searchBar;

- ( id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
     if (self) {
         //  Custom initialization
    }
     return self;
}

- ( void)viewDidLoad
{
     //  获取plist资源文件地址
    NSString *path = [[NSBundle mainBundle] pathForResource: @" data " ofType: @" plist "];
    
     //  这是写入日记,为了调试,不是必须的
    NSLog( @" 资源文件路径: %@ ",path);
    
     //  根据文件路径获取字典内容
    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
    self.movieTitles = dict;
    
     //  根据字典,获得年份的数组
    NSArray *array = [[movieTitles allKeys] sortedArrayUsingSelector:@selector(compare:)];
    self.years = array;
    
     //  原来应该有如下两句,xcode 4.2以后,启用ARC之后,就不需要了
    
// [dict release];
    
// [array release];
    
    
//  设置视图的搜索框
    self.tableView.tableHeaderView = searchBar;
    searchBar.autocorrectionType = UITextAutocorrectionTypeYes;
    
     //  初始化电影列表
    listOfMovies = [[NSMutableArray alloc]init];
     for(NSString *year  in array)
    {
        NSArray *movies = [movieTitles objectForKey:year];
         for (NSString *title  in movies) {
            [listOfMovies addObject:title];
        }
    }
    
     //  初始化搜索结果数组
    searchResult = [[NSMutableArray alloc] init];
    
     //  设置状态
    isSearchOn = NO;
    canSelectRow = YES;

    
    [super viewDidLoad];
}

- ( void)viewDidUnload
{
    self.movieTitles = nil;
    self.years = nil;
    
    self.searchBar = nil;
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
     return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
     //  返回节点数,就是显示几个组,我们这里是按年份显示数据
     if (isSearchOn) {
         return  1;   //  进入搜索状态,只有一个节点
    }  else {
         return  [years count];
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     if (isSearchOn)
    {
         return [searchResult count];   //  搜索结果的数量
    }
     else
    {
         //  获取当前节点的年份
        NSString *year = [years objectAtIndex:section];
    
         //  根据节点的年份,获取字节点的数组
        NSArray *movieSection = [movieTitles objectForKey:year];
    
         //  返回当前字节的数量
         return [movieSection count];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString *CellIdentifier =  @" MovieCell ";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
     if (isSearchOn) {
        NSString *title = [searchResult objectAtIndex:indexPath.row];
        cell.textLabel.text = title;
    }  else {
         //  获取节点的年份
        NSString *year = [years objectAtIndex:[indexPath section]];
    
         //  获取年份内所有电影数组
        NSArray *movie = [movieTitles objectForKey:year];
    
         //  根据数组获取电影的标题
        cell.textLabel.text = [movie objectAtIndex:[indexPath row]];
        cell.detailTextLabel.text =  @" 主演:周星驰 ";
    }
     return cell;
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
     if (isSearchOn)
    {
         return  nil;
    }
     else
    {
         //  获取年份
        NSString   *year = [years objectAtIndex:section];
         return  year;
    }
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

#pragma mark - Table view delegate

- ( void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
     //  Navigation logic may go here. Create and push another view controller.
     /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     
*/
}


#pragma mark - 添加搜索方法与事件

//  事件:搜索框开始输入字符
-( void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
     //  进入搜索状态
    isSearchOn = YES;
    
     //  不能选择行
    canSelectRow = NO;
    
     //  关闭滚动条的显示
    self.tableView.scrollEnabled = NO;
}

//  事件:搜索框中文字发生变化触发
-( 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) searchMoviesTableView
{
    [searchResult removeAllObjects];
     for (NSString *str  in listOfMovies) {
        NSRange titleResultsRange=[str rangeOfString:searchBar.text
                                             options:NSCaseInsensitiveSearch];
         if(titleResultsRange.length> 0)
            [searchResult addObject:str];
    }
    
}

//  事件:键盘上的搜索按钮事件
-( void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    [self searchMoviesTableView];
}

//  事件:搜索框里取消按钮事件
-( void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    isSearchOn = NO;
    canSelectRow = YES;
    self.tableView.scrollEnabled = YES;
    self.navigationItem.rightBarButtonItem = nil;
    
    [self.searchBar resignFirstResponder];
    [self.tableView reloadData];
}

@end

 

12. View与Controller 绑定一下关系(如何绑定?如有不懂的童鞋,请找谷老师)

 

 

13. 最终效果图如下:

 

 

14. 附上代码地址:源代码

 

搞定,收工,开周例会


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM