Iphone开发基础教程 (8章 表视图)--读书笔记

表视图是显示表数据的视图对象,它是UITableView类的一个实例,表中的每个可见行都由UITableviewCell类实现。

表视图并不负责存储表中的数据,他们只存储足够绘制当前可见行的数据。

表视图从遵循UITableviewDelegate协议的对象获取配置数据,从遵循UITableviewDataSource协议的对象获得行数据。

第一个例子:SimpleTable

1、新建Single View Application项目

2、打开ViewController.xib,拖出一个TableView到界面上,在Connection里,将dataSource和delegate连接到File's Owner上

3、修改控制器

ViewController.h

@interface ViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>
{
    NSArray *listData;
}
@property (nonatomic,retain) NSArray *listData;

@end
ViewController.m
@implementation ViewController

@synthesize listData;

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    NSArray *array = [[NSArray alloc] initWithObjects:@"Sleep",@"Sneey",
                      @"Bashful",@"Happy",nil];
    self.listData = array;
    [array release];
    [super viewDidLoad];
}

- (void)dealloc {
    [listData release];
    [super dealloc];
}

- (NSInteger)tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.listData count];
}
//当表视图需要绘制其中一行时,会调用次方法
-(UITableViewCell *) tableView:(UITableViewCell *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SimpleTableIdentifier] autorelease];
    }
    NSUInteger row = [indexPath row];
    cell.text = [listData objectAtIndex:row];
    return cell;
}
4、运行

添加一个图像

1、添加icon图像资源到项目中

2、修改ViewController.m

//当表视图需要绘制其中一行时,会调用次方法
-(UITableViewCell *) tableView:(UITableViewCell *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SimpleTableIdentifier] autorelease];
    }
    NSUInteger row = [indexPath row];
    cell.text = [listData objectAtIndex:row];
    cell.font = [UIFont boldSystemFontOfSize:40];
    UIImage *image = [UIImage imageNamed:@"plane.jpg"];
    cell.image = image;
    return cell;
}

设置图像缩进

//设置每一行的缩进
-(NSInteger)tableView:(UITableView *) tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = [indexPath row];
    return row;
}

设置第一列不能点钟

-(NSIndexPath *)tableView:(UITableView *) tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = [indexPath row];
    if (row == 0) {
        return nil;
    }
    return indexPath;
}

点击每一列,弹出一个对话框

-(void)tableView:(UITableView *) tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = [indexPath row];
    NSString *rowValue = [listData objectAtIndex:row];
    NSString *message = [[NSString alloc] initWithFormat:@"You selected %@",rowValue];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Row Selected" message:message delegate:nil cancelButtonTitle:@"Yes,I Did" otherButtonTitles:nil, nil];
    [alert show];
    [message release];
    [alert release];
}
字体变大
//当表视图需要绘制其中一行时,会调用次方法
-(UITableViewCell *) tableView:(UITableViewCell *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SimpleTableIdentifier] autorelease];
    }
    NSUInteger row = [indexPath row];
    cell.text = [listData objectAtIndex:row];
    cell.font = [UIFont boldSystemFontOfSize:40];
    UIImage *image = [UIImage imageNamed:@"plane.jpg"];
    cell.image = image;
    return cell;
}
每一列高度加大

-(CGFloat)tableView:(UITableView *) tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 80;
}

第二个例子:自定义表视图单元

可以采用两种方法,一是向UITableViewCell添加子视图,二是,创建一个UITableViewCell的子类
1、参考例子一,新建项目,打开xib文件,视图拖出一个TableView视图,dataSource dataDelegate连接到File's Owner上
2、修改控制器
#import <UIKit/UIKit.h>
#define kNameValueTag 1  //定义了两个常量,将使用这两个常量为将要添加到表视图中的子视图分配标记
#define kColorValueTag 2

@interface ViewController : UIViewController<UITabBarDelegate,UITabBarDelegate>
{
    NSArray *computers;
}

@property (nonatomic,retain) NSArray *computers;

@end
@implementation ViewController

@synthesize computers;

- (void)viewDidLoad
{
    NSDictionary *row1 = [[NSDictionary alloc] initWithObjectsAndKeys:@"MacBook",@"Name",@"White",@"Color", nil];
    NSDictionary *row2 = [[NSDictionary alloc] initWithObjectsAndKeys:@"MacBook Pro",@"Name",@"Silver",@"Color", nil];
    NSDictionary *row3 = [[NSDictionary alloc] initWithObjectsAndKeys:@"iMac",@"Name",@"White",@"Color", nil];
    NSArray *array = [[NSArray alloc] initWithObjects:row1,row2,row3, nil];
    self.computers = array;
    [super viewDidLoad];
    [row1 release];
    [row2 release];
    [row3 release];
    [array release];
}

- (void)dealloc {
    [computers release];
    [super dealloc];
}

-(NSInteger)tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.computers count];
}

-(UITableViewCell *)tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellTableIdentfier = @"CellTableIdentfier";  //创建了一个新的单元
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentfier];  //如果表提供了出列的表视图单元,则要求表将该单元推出队列
    if (cell == nil) {
        CGRect cellFrame = CGRectMake(0, 0, 300, 65);
        cell = [[[UITableViewCell alloc] initWithFrame:cellFrame reuseIdentifier:CellTableIdentfier] autorelease];
       
        CGRect nameLabelRect = CGRectMake(0, 5, 70, 15);
        UILabel *nameLabel = [[UILabel alloc] initWithFrame:nameLabelRect];
        nameLabel.textAlignment = UITextAlignmentRight;
        nameLabel.text = @"Name:";
        nameLabel.font = [UIFont boldSystemFontOfSize:12];
        [cell.contentView addSubview:nameLabel];
        [nameLabel release];
        
        CGRect colorLabelRect = CGRectMake(0, 25, 70, 15);
        UILabel *colorLabel = [[UILabel alloc] initWithFrame:colorLabelRect];
        colorLabel.textAlignment = UITextAlignmentRight;
        colorLabel.text = @"Color:";
        colorLabel.font = [UIFont boldSystemFontOfSize:12];
        [cell.contentView addSubview:colorLabel];
        [colorLabel release];
        
        CGRect nameValueRect = CGRectMake(80, 5, 200, 15);;
        UILabel *nameValue = [[UILabel alloc] initWithFrame:nameValueRect];
        nameValue.tag = kNameValueTag;
        [cell.contentView addSubview:nameValue]; //表视图单元已经有了一个名为contentView的UIView子视图,用于对它的所有子视图进行分组。不用把标签作为子视图直接添加到表视图单元,而是添加到contentView
        [nameValue release];
        
        CGRect colorValueRect = CGRectMake(80, 25, 200, 15);;
        UILabel *colorValue = [[UILabel alloc] initWithFrame:colorValueRect];
        colorValue.tag = kColorValueTag;
        [cell.contentView addSubview:colorValue];
        [colorValue release];
    }
    NSUInteger row = [indexPath row];
    NSDictionary *rowData = [self.computers objectAtIndex:row];
	// 检索到标签以后,只需将标签文本设置为从表示此行的字典里获取的一个值
UILabel *name = (UILabel *)[cell.contentView viewWithTag:kNameValueTag]; name.text = [rowData objectForKey:@"Name"]; UILabel *color = (UILabel *)[cell.contentView viewWithTag:kColorValueTag]; color.text = [rowData objectForKey:@"Color"]; return cell;}

第三个例子:使用UITableViewCell自定义子类

1、在第二个例子的基础上做修改,新建UIViewController subclass 名为CustomCell,继承自UITableViewCell,注意勾选 With XIB ...





2、修改控制器
@interface CustomCell : UITableViewCell{
    IBOutlet UILabel *nameLabel;
    IBOutlet UILabel *colorLabel;
}

@property (nonatomic,retain) UILabel *nameLabel;
@property (nonatomic,retain) UILabel *colorLabel;
@implementation CustomCell

@synthesize nameLabel;
@synthesize colorLabel;
3、打开CustomView.xib,拖一个Table View Cell到dock上(不是界面上),把dock的view删掉
选中Table View Cell 将class改为 CustomCell ,高度改为65,属性面板:Identifier改为CustomCellIdentifier
拖4个label到界面上,排列好
按Control 把Custom Cell图标拖到Label图标上,在弹出的框,选择nameLabel输出口,重复实现colorLabel


4、修改控制器文件
替换掉原来的 cellForRowAtIndexPath方法
- (UITableViewCell *) tableView:(UITableViewCell *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CustomCellIdentifier = @"CustomCellIdentifier";
    CustomCell *cell = [tableView  dequeueReusableCellWithIdentifier:CustomCellIdentifier];
    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }
    NSInteger row = [indexPath row];
    NSDictionary *rowData = [self.computers objectAtIndex:row];
    cell.colorLabel.text = [rowData objectForKey:@"Color"];
    cell.nameLabel.text = [rowData objectForKey:@"Name"];
    return cell;
}

-(CGFloat)tableView:(UITableView *) tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return kTableViewRowHeight;
}
5、在头文件中,修改如下
6、运行,看效果


第四个例子:分组分区索引分区

1、参照例一,新建项目,打开xib文件,视图拖出一个TableView视图,dataSource dataDelegate连接到File's Owner上

2、打开ViewController.xib,选中表视图,把表视图的Style改为Grouped


3、导入数据文件storednames.plist

4、修改控制器

@interface ViewController : UIViewController<UITabBarDelegate,UITabBarDelegate>
{
    NSDictionary *names;
    NSArray *keys;
}

@property (nonatomic,retain) NSDictionary *names;
@property (nonatomic,retain) NSArray *keys;

@implementation ViewController

@synthesize names;
@synthesize keys;

- (void)viewDidLoad {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"sortednames"
                                                     ofType:@"plist"];
    NSDictionary *dict = [[NSDictionary alloc] 
                          initWithContentsOfFile:path];
    self.names = dict;
    [dict release];
    
    NSArray *array = [[names allKeys] sortedArrayUsingSelector:
                      @selector(compare:)];
    self.keys = array;
}

- (void)viewDidUnload {
    self.names = nil;
    self.keys = nil;
}
- (void)dealloc {
    [names release];
    [keys release];
    [super dealloc];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [keys count];
}
- (NSInteger)tableView:(UITableView *)tableView 
 numberOfRowsInSection:(NSInteger)section
{
    NSString *key = [keys objectAtIndex:section];
    NSArray *nameSection = [names objectForKey:key];
    return [nameSection count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger section = [indexPath section];
    NSUInteger row = [indexPath row];
    
    NSString *key = [keys objectAtIndex:section];
    NSArray *nameSection = [names objectForKey:key];
    
    static NSString *SectionsTableIdentifier = @"SectionsTableIdentifier";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
                             SectionsTableIdentifier ];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier: SectionsTableIdentifier ] autorelease];
    }
    
    cell.text = [nameSection objectAtIndex:row];
    return cell;
}
- (NSString *)tableView:(UITableView *)tableView 
titleForHeaderInSection:(NSInteger)section
{
    NSString *key = [keys objectAtIndex:section];
    return key;
}
//添加如下方法,可以显示索引表
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    return keys;
}

第四个例子:实现搜索栏

我们拥有一个包含多个数组的字典,其中字母表的每个字母都占有一个数组,该字典是不可改变的,这就意为着不能从字典添加或删除,它包含的数组也是如此。当用户取消搜索或者更改搜索项时,还必须能够返回到源数据集。
我们能做的就是创建两个新的字典:一个包含完整数据集的不可变的字典、一个可以从中删除行的可变的字典副本。委托和数据源将从可变字典进行读取,当搜索标准更改或者取消搜索时,可以从不可改变的字典刷新可变字典。

1、新建Empty File 文件名:NSDdictionary-MutableDeepCopy.m  NSDdictionary-MutableDeepCopy.h
@interface NSDictionary (MutableDeepCopy)
-(NSMutableDictionary *) mutableDeepCopy;
@end
@implementation NSDictionary (MutableDeepCopy)

- (NSMutableDictionary *) mutableDeepCopy
{
    NSMutableDictionary *ret = [NSMutableDictionary dictionaryWithCapacity:[self count]];
    NSArray *keys = [self allKeys];
    for (id key in keys) {
        
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;
        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)]) 
            oneCopy = [oneValue mutableDeepCopy];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)]) 
            oneCopy = [oneValue mutableCopy];
        else
            oneCopy = [oneValue copy];
        [ret setValue:oneCopy forKey:key];
    }
    return ret;                     
}

@end
@interface ViewController : UIViewController<UITabBarDelegate,UITabBarDelegate,UISearchBarDelegate>
{
    //NSDictionary *names;
    //NSArray *keys;
    
    IBOutlet UITableView *table;
    IBOutlet UISearchBar *search;
    NSDictionary *allNames;
    NSMutableDictionary *names;
    NSMutableArray *keys;
}

@property (nonatomic,retain) UITableView *table;
@property (nonatomic,retain) UISearchBar *search;
@property (nonatomic,retain) NSDictionary *allNames;
@property (nonatomic,retain) NSMutableDictionary *names;
@property (nonatomic,retain) NSMutableArray *keys;

-(void) resetSearch;
-(void) handleSearchFroTerm:(NSString *) searchTerm;

@end
@implementation ViewController

@synthesize names;
@synthesize keys;
@synthesize table;
@synthesize search;
@synthesize allNames;

-(void)resetSearch
{
    self.names = [self.allNames mutableDeepCopy];
    NSMutableArray *keyArray = [[NSMutableArray alloc] init];
    [keyArray addObjectsFromArray:[[self.allNames allKeys] sortedArrayUsingSelector:@selector(compare:)]];
    
    self.keys = keyArray;
    [keyArray release];
}

- (void) handleSearchFroTerm:(NSString *)searchTerm
{
    NSMutableArray *sectionsToRemove = [[NSMutableArray alloc]init];
    [self resetSearch];
    
    for (NSString *key in self.keys){
        NSMutableArray *array = [names valueForKey:key];
        NSMutableArray *toRemove = [[NSMutableArray alloc] init];
        for (NSString *name in array){
            if ([name rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location == NSNotFound) {
                [toRemove addObject:name];
            }
            if ([array count] == [toRemove count]) {
                [sectionsToRemove addObject:toRemove];
                [toRemove release];
            }
        }
        [self.keys removeObjectsInArray:sectionsToRemove];
        [sectionsToRemove release];
         [table reloadData];
                                 
    }
}



- (void)viewDidLoad {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"sortednames"
                                                     ofType:@"plist"];
    NSDictionary *dict = [[NSDictionary alloc] 
                          initWithContentsOfFile:path];
    //self.names = dict;
    self.allNames =dict;
    [dict release];
    
    //NSArray *array = [[names allKeys] sortedArrayUsingSelector: @selector(compare:)];
    //self.keys = array;
    [self resetSearch];
    search.autocapitalizationType = UITextAutocapitalizationTypeNone;
    search.autocorrectionType =UITextAutocorrectionTypeNo;
}



- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
    self.names = nil;
    self.keys = nil;
}
- (void)dealloc {
    [table release];
    [search release];
    [allNames release];
    [names release];
    [keys release];
    [super dealloc];
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    //return [keys count];
    return ([keys count]>0)?[keys count]:1;
}
- (NSInteger)tableView:(UITableView *)tableView 
 numberOfRowsInSection:(NSInteger)section
{
    if ([keys count] == 0) {
        return 0;
    }
    NSString *key = [keys objectAtIndex:section];
    NSArray *nameSection = [names objectForKey:key];
    return [nameSection count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger section = [indexPath section];
    NSUInteger row = [indexPath row];
    
    NSString *key = [keys objectAtIndex:section];
    NSArray *nameSection = [names objectForKey:key];
    
    static NSString *sectionsTableIdentifier = @"sectionsTableIdentifier";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
                             sectionsTableIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:sectionsTableIdentifier] autorelease];
    }
    
    cell.text = [nameSection objectAtIndex:row];
    return cell;
}
- (NSString *)tableView:(UITableView *)tableView 
titleForHeaderInSection:(NSInteger)section
{
    if ([keys count] == 0) {
        return @"";
    }
    NSString *key = [keys objectAtIndex:section];
    return key;
}

- (NSArray *) sectionIndexTitleForTableView:(UITableView *) tableview
{
    return keys;
}
- (NSIndexPath *) tableView:(UITableView *) tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [search resignFirstResponder];
    return indexPath;
}



- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    NSString *searchTerm = [searchBar text];
    [self handleSearchFroTerm:searchTerm];
}

-(void)searchBar:(UISearchBar *) searchBar textDidChange:(NSString *)searchText
{
    if ([searchText length] == 0) {
        [self resetSearch];
        [table reloadData];
        return;
    }
    [self handleSearchFroTerm:searchText];
}

-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    searchBar.text = @"";
    [self resetSearch];
    [table reloadData];
    [searchBar resignFirstResponder];
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    return keys;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值