您的位置:首页 > 产品设计 > UI/UE

UITableView详细讲解2

2012-07-31 18:06 309 查看
UITableView的详细讲解

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 <UIKit/UIFont.h>

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 <UIKit/UIColor.h>

//文本颜色

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<1)
{

[self doubleTap];

}

taptime = curr;

}

点击变色再恢复

[_tableView deselectRowAtIndexPath:indexPath animated:YES];

分别是折叠状态的tableview和展开状态的tableview

运行效果如下,分别是折叠状态的tabview和展开状态的tabview:

一、新建UITableViewController

.h文件如下,包含了一个用于显示的视图tableview和用于表示模型数据的MutableArray.

@interface GDXXDetailVC :UITableViewController

<UITableViewDelegate,UITableViewDataSource,UIActionSheetDelegate>

{

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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: