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