1. UITableView的初始化
UITableView tableview= [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)];
[tableview setDelegate:self];
[tableview setDataSource:self];
[self.view addSubview: tableview];
[tableview release];
(1)在初始化UITableView的时候必须实现UITableView的 是,在.h文件中要继承UITableViewDelegate和UITableViewDataSource,并实现3个UITableView数据源 方法和设置它的delegate为self,这个是在不直接继承UITableViewController实现的方法。
(2) 直接在XCODE生成项目的时候继承UITableViewController的,它会帮你自动写好UITableView必须要实现的方法。
(3)UITableView继承自UIScrollView。
2. UITableView的数据源
(1)UITableView是依赖外部资源为新表格单元填上内容的,我们称为数据源,这个数据源可以根据索引路径提供表格单元格,在UITableView中,索引路径是NSIndexPath的对象,可以选择分段或者分行,即是我们编码中的section和row。
(2)UITableView有三个必须实现的核心方法,分别如下:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
这个方法可以分段显示或者单个列表显示我们的数据。如下,左边为分段显示,右边为单个列表显示:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
这个方法返回每个分段的行数,不同分段返回不同的行数可以用switch来做,如果是单个列表就直接返回单个你想要的函数即可。
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
这个方法是返回我们调用的每一个单元格。通过我们索引的路径的section和row来确定。
3. UITableView的委托方法
使用委托是为了响应用户的交互动作,比如下拉更新数据和选择某一行单元格,在UITableView中有很大这种方法供我们选择。
(1) 委托方法讲解
//设置Section的数量
-(NSArray*)sectionIndexTitlesForTableView:(UITableView *)tableView
//设置每个section显示的Title
//设置每个section显示的Title
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *key = [m_titleArrayobjectAtIndex:section];
return key;
}
//指定有多少个分区(Section),默认为1
//分区的数量
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return4;
}
//指定每个分区中有多少行,默认为1
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
sectionArray = [myDictionary objectForKey:[m_titleArray objectAtIndex:section]];
return [sectionArray count];
}
//设置每行调用的cell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
NSString *theSection = [m_titleArrayobjectAtIndex:indexPath.section];
//NSLog(@"theSection=%@",theSection);
//声明一个标识符,然后使用它请求可重用单元
staticNSString *CellIdentifier =@"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//如果没有可重用单元,则创建一个
//使用前面提到的标识符字符串手动创建一个新的表视图单元。我们将不可避免地重复使用此处创建的单元。
if (!cell) {
cell = [[[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier] autorelease];
}
sectionArray = [myDictionaryobjectForKey:theSection];
NSString *singername = [sectionArrayobjectAtIndex:indexPath.row];
cell.textLabel.text = singername;
cell.textLabel.font = [UIFontboldSystemFontOfSize:30];
cell.imageView.image = [UIImageimageNamed:[NSStringstringWithFormat:@"%@.png",singername]];//未选中cell时的图片
cell.imageView.highlightedImage = [UIImageimageNamed:@""];//选中cell后的图片
cell.showsReorderControl =YES;
cell.accessoryType =UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
//设置让UITableView行缩进
//把每行的缩进级别设置为其行号,第0号缩进级别为0,第1行缩进级别为1.
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath*)indexPath
{
NSUInteger row = indexPath.row;
return row;
}
//设置cell每行间隔的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return75;
}
//返回当前所选cell
NSIndexPath *ip = [NSIndexPath indexPathForRow:row inSection:section];
[_tableView selectRowAtIndexPath:ipanimated:YES scrollPosition:UITableViewScrollPositionNone];
//设置UITableView的SeparatorStyle
_tableview.separatorStyle = UITableViewCellSeparatorStyleNone;
//设置选中Cell的响应事件
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[m_tableview deselectRowAtIndexPath:indexPath animated:YES];//选中后的反显颜色即刻消失
}
//选中之前执行(阻止选中第一行)
-(NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
NSLog(@"willSelectRowAtIndexPath");
NSUInteger row = [indexPath row];
if (row == 0) {
return nil;
}
return indexPath;
}
//设置划动cell是否出现del按钮
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
returnYES;
}
//设置删除时编辑状态
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle ==UITableViewCellEditingStyleDelete)
{
[sectionArray removeObjectAtIndex:indexPath.row];
[m_tableview deleteRowsAtIndexPaths:[NSMutableArrayarrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationTop];
}
}
//右侧添加一个索引表
//在表视图右侧添加一个索引
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return m_titleArray;
}
//跳到指定的row or section
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
(2) 其他
//选中cell时的颜色,在官方文档有如下可以选择
//选中项的风格
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
typedef enum {
UITableViewCellSelectionStyleNone, 没有变化
UITableViewCellSelectionStyleBlue, 默认选中项是蓝色
UITableViewCellSelectionStyleGray 灰色
} UITableViewCellSelectionStyle
//cell右边按钮格式
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
typedef enum {
UITableViewCellAccessoryNone, //没有附件
UITableViewCellAccessoryDisclosureIndicator, //黑色向右的箭头
UITableViewCellAccessoryDetailDisclosureButton, //蓝色附件按钮
UITableViewCellAccessoryCheckmark //复选框,支持选择
} UITableViewCellAccessoryType
实现多选
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Selected section %d, cell %d",
[ indexPath indexAtPosition: 0 ], [ indexPath indexAtPosition: 1 ]);
//获的当前选择项
UITableViewCell *cell = [ self.tableView cellForRowAtIndexPath: indexPath ];
//显示复选框
if (cell.accessoryType == UITableViewCellAccessoryNone)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
}
//UITableView单元格颜色交替
由于设置单元格背景颜色只能在UITextViewDelegate代理函数willDisplayCell中有效,所以在该函数中可以设置颜色交替
//行将显示的时候调用
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{ //方法一:
UIColor *color = ((indexPath.row %2) ==0) ? [UIColorcolorWithRed:255.0/255green:255.0/255blue:145.0/255alpha:1] : [UIColorclearColor];
cell.backgroundColor = color;
NSLog(@"willDisplaycell");
//方法二:
if (indexPath.row %2 ==1)
{
cell.backgroundColor = [UIColoryellowColor];
}
else
{
cell.backgroundColor = [UIColorredColor];
cell.selectedBackgroundView = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"cell_1.png"]];//选中cell行变图片
}
}
//是否加换行线
typedef enum {
UITableViewCellSeparatorStyleNone,
UITableViewCellSeparatorStyleSingleLine
} UITableViewCellSeparatorStyle
//改变换行线颜色
tableView.separatorColor= [UIColor blueColor];
4. UITableViewCell
表中的每一行都代表一个UITableViewCell。可以使用图像、文本还有辅助的图标等来自定义你自己的UITableViewCell。你可以自定义你自己的cell如下模型或者像appstore那样的。
UITableViewCell为每个Cell提供了三个可以选择的属性,如下:
l textLabel:填写文本
l detailTextLable:稍微详细的副标题
l imageView:用来显示你cell的图片,可以通过UIImage来加载。
(1) 显示文本: cell.text = @"Frank's Table Cell";
(2) 对齐: cell.textAlignment = UITextAlignmentLeft;
UITextAlignmentLeft 默认是左对齐
UITextAlignmentRight 右对齐
UITextAlignmentCenter 中对齐
(3) 字体和尺寸:
#import
UIFont *myFont = [ UIFont fontWithName: @"Arial" size: 18.0 ];
cell.font = myFont;
//系统字体
UIFont *mySystemFont = [ UIFont systemFontOfSize: 12.0 ];
UIFont *myBoldSystemFont = [ UIFont boldSystemFontOfSize: 12.0 ];
UIFont *myItalicSystemFont = [ UIFont italicSystemFontOfSize: 12.0 ];
(4) 颜色
#import
//文本颜色
cell.textColor = [UIColor redColor];
//当前选择cell文本的颜色
cell.selectedTextColor = [UIColor blueColor];
(5) 图像
//从你应用程序目录下的文件创建一个image
cell.image = [UIImage imageNamed: @"cell.png"];
//当前选中项的图形
cell.selectedImage = [UIImage imageNamed: @"selected_cell.png" ];//选中cell后左边图片换
//选中后变图片
cell.leftImageView.highlightedImage = [UIImageimageNamed:@"china_national_day-2011-hp.jpg"];
可以修改table保准行高来适应你的图形高度
- (id)init
{
self = [ super init ];
if (self != nil) {
self.tableView.rowHeight = 65;
}
return self;
}
你也可以为每一个cell定义不同的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([ indexPath indexAtPosition: 1 ] == 0)
return 65.0;
else
return 40.0;
}
最后给出一个官方的demo给大家学习下,多实践,不懂的就问下,下节课讲些UITableView应用中实际会出现的问题,比如自定义啊,重用单元格,单元格的数据排序等问题。欢迎大家拍砖。
附上代码:http://www.2cto.com/uploadfile/2011/1130/20111130025401502.zip
修改cell选中后的颜色
UIView *backView = [[UIView alloc]initWithFrame:CGRectMake(0,0,320,80)];
cell.selectedBackgroundView = backView;
cell.selectedBackgroundView.backgroundColor = [UIColor orangeColor];
[backView release];
设置tableView偏移
// tableView内容的偏移值,第一个参数为Y方向
tableView.contentInset = UIEdgeInsetsMake(64,0,0,0);
修改UITableView中Delete操作的默认按钮
默认的删除按钮为Delete,如果想显示为删除的话,则需要实现UITableViewDelegate中的
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath方法。
//删除按钮的名字
-(NSString*)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
return@"删除按钮";
}
或者,最简单的方式,将plist中的Localization native development region改为China即可。
UITableView在didSelectRowAtIndexPath实现双击事件的方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//如果两次点击的时间间隔小于1秒,则断定为双击事件
NSUInteger curr = [[NSDate date] timeIntervalSince1970];
if (curr-taptime<</span>1) {
[self doubleTap];
}
taptime = curr;
}
点击变色再恢复
[_tableView deselectRowAtIndexPath:indexPath animated:YES];
分别是折叠状态的tableview和展开状态的tableview
运行效果如下,分别是折叠状态的tabview和展开状态的tabview:
一、新建UITableViewController
.h文件如下,包含了一个用于显示的视图tableview和用于表示模型数据的MutableArray.
@interface GDXXDetailVC :UITableViewController
{
UITableView* tableView;
NSMutableArray* model;
UIBarButtonItem *btnSave;
NSString *account,*pass;
NSArray* keys;
}
-(void)setModel:(NSString*)_account pass:(NSString*)_pass data:(NSArray*)_data;
-(void)save;
-(void)collapseOrExpand:(int)section;
-(Boolean)isExpanded:(int)section;
@end
.m文件如下,包含了tableview的datasource方法,和模型的处理逻辑。
#import "GDXXDetailVC.h"
@implementation GDXXDetailVC
-(id)init{
if(self=[super init]){
self.title=@"工单处理";
}
return self;
}
-(void)setModel:(NSString*)_account pass:(NSString*)_pass data:(NSArray*)_data
{
account=_account;
pass=_pass;
model=[[NSMutableArray alloc]init];
[model setArray:_data];
[_data release];
}
-(void)loadView{
self.view=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
tableView=[[UITableView alloc]initWithFrame:CGRectMake(0, 20, 320, 480) style:UITableViewStyleGrouped];
[self.view addSubview:tableView];
tableView.delegate=self;
tableView.dataSource=self;
//这个图片中工具栏中显示一个保存按钮
btnSave= [[UIBarButtonItem alloc]
initWithTitle:@"处理"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(save)];
self.navigationItem.rightBarButtonItem = btnSave;
[btnSave release];
}
-(void)saveData{
}
#pragma mark Actionsheet 委托方法
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{//当ActionSheet的某个按钮被按下时触发
if(buttonIndex == 0)//第一个按钮表示保存按钮
{
[self performSelector:@selector(saveData)];
}
//解散actionSheet
[actionSheet dismissWithClickedButtonIndex: buttonIndex animated:YES];
}
#pragma mark ===table view dataSource method and delegate method===
//返回分组数
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [model count];
}
//返回组标题
//-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
//{
// NSDictionary* d=[model objectAtIndex:section];
// if(d!=nil)
//title=[d objectForKey:@"title"];
// else return nil;
//}
//自定义section header
- (UIView *) tableView: (UITableView *) tableView
viewForHeaderInSection: (NSInteger) section
{
NSString*title=@"notitle";
NSDictionary* d=[model objectAtIndex:section];
if(d!=nil)
title=[d objectForKey:@"title"];
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
UIView* footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenRect.size.width, 44.0)];
footerView.autoresizesSubviews = YES;
footerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
footerView.userInteractionEnabled = YES;
footerView.hidden = NO;
footerView.multipleTouchEnabled = NO;
footerView.opaque = NO;
footerView.contentMode = UIViewContentModeScaleToFill;
// Add the label
UILabel* footerLabel = [[UILabel alloc] initWithFrame:CGRectMake(64, 5, 120.0, 45.0)];
footerLabel.backgroundColor = [UIColor clearColor];
footerLabel.opaque = NO;
footerLabel.text = title;
footerLabel.textColor = [UIColor blackColor];
footerLabel.highlightedTextColor = [UIColor blueColor];
footerLabel.font = [UIFont boldSystemFontOfSize:17];
footerLabel.shadowColor = [UIColor whiteColor];
footerLabel.shadowOffset = CGSizeMake(0.0, 1.0);
[footerView addSubview: footerLabel];
[footerLabel release];
// Add the button
UIButton* footerButton = [[UIButton alloc] initWithFrame:CGRectMake(12, 5, 48.0, 48.0)];
//一开始小节是处于“折叠状态”,“+/-”按钮显示“+号”图标
if ([self isExpanded:section]) {//若本节转换到“展开”状态,需要把图标显示成“-”号
[footerButton setBackgroundImage:[UIImage imageNamed:@"minus.png"] forState:UIControlStateNormal];
}else
[footerButton setBackgroundImage:[UIImage imageNamed:@"plus.png"] forState:UIControlStateNormal];
[footerButton addTarget:self action:@selector(expandButtonClicked:)
forControlEvents:UIControlEventTouchUpInside];
footerButton.tag=section;//把节号保存到按钮tag,以便传递到expandButtonClicked方法
[footerView addSubview: footerButton];
[footerButton release];
// Return the footerView
return footerView;
}
//当“+/-”按钮被点击时触发
-(void)expandButtonClicked:(id)sender{
UIButton* btn=(UIButton*)sender;
int section=btn.tag; //取得节号
[self collapseOrExpand:section];
//刷新tableview
[tableView reloadData];
}
//对指定的节进行“展开/折叠”操作
-(void)collapseOrExpand:(int)section{
Boolean expanded=NO;
NSMutableDictionary* d=[model objectAtIndex:section];
//若本节model中的“expanded”属性不为空,则取出来
if([d objectForKey:@"expanded"]!=nil)
expanded=[[d objectForKey:@"expanded"]intValue];
//若原来是折叠的则展开,若原来是展开的则折叠
[d setObject:[NSNumber numberWithBool:!expanded] forKey:@"expanded"];
}
//返回指定节的“expanded”值
-(Boolean)isExpanded:(int)section{
Boolean expanded=NO;
NSMutableDictionary* d=[model objectAtIndex:section];
//若本节model中的“expanded”属性不为空,则取出来
if([d objectForKey:@"expanded"]!=nil)
expanded=[[d objectForKey:@"expanded"]intValue];
return expanded;
}
// 设置header的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 60;
}
//返回分组的行数
-(NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section{
//对指定节进行“展开”判断
if (![self isExpanded:section]) {//若本节是“折叠”的,其行数返回为0
return 0;
}
NSDictionary* d=[model objectAtIndex:section];
return [[d objectForKey:@"items"] count];
}
//设置行高
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 50;
}
//设置每一单元格的内容
-(UITableViewCell*)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString*
cellId=@"setcell
";
UITableViewCell* cell=(UITableViewCell*)[table dequeueReusableCellWithIdentifier:cellId];
if(cell==nil){
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:cellId]autorelease];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
NSDictionary* items=[[model objectAtIndex:indexPath.section] objectForKey:@"items"];
keys=[items allKeys];
cell.textLabel.text=[items objectForKey:[keys objectAtIndex:indexPath.row]];
cell.textLabel.font=[UIFont fontWithName:@"Arial" size:18.0];
return cell;
}
//单元格选中时触发
-(void)tableView:(UITableView *)table didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
-(void)save{
}
-(void)dealloc{
[model release];
[tableView release];
[super dealloc];
}
@end
二、在application的AppDelegate中实例化TableViewController
在application方法中,构造好一个Array,把要展示的数据放到其中,然后调用TableViewController的setModel方法设置tableview的model。这个Array的结构应该是这样的:
NSArray 中的元素为NSMutableDictionary(必须是Mutable,不能是NSDictionary)。每一个 NSMutableDictionary代表了一个小节的数据,包含若干key-value,其中Title为小节名称,expanded为小节的展开/ 折叠状态,items为小节中每一行的数据。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
window=[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
GDXXDetailVC* rootController=[[GDXXDetailVC alloc]init];
NSMutableArray* items=[[NSMutableArray alloc]init];
for (int i=1; i<10; i++) {
NSDictionary *d=[NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:@"section %d item1",i],@"1",
[NSString stringWithFormat:@"section %d item2",i],@"2",
[NSString stringWithFormat:@"section %d item3",i],@"3",
nil];
NSMutableDictionary* dic=[NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:@"title %d",i],@"title",
d,@"items",[NSNumber numberWithBool:NO],@"expanded",
nil];
//[d release];
[items addObject:dic];
//[dic release];
}
[rootController setModel:nil pass:nil data:items];
//[items release];
[rootController setTitle:@"无线应用"];
[window addSubview:rootController.view];
//[rootController release];
[window makeKeyAndVisible];
return YES;