UITableView的基本知识讲解

来源:互联网 发布:金十数据图 编辑:程序博客网 时间:2024/06/01 07:11

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,nilwithRowAnimation:UITableViewRowAnimationTop];

 

 }

}

 

//右侧添加一个索引表

//在表视图右侧添加一个索引

-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView

{

    return m_titleArray;

}

 


//跳到指定的row or section

 

[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0inSection:0atScrollPosition: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 datetimeIntervalSince1970];

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;
原创粉丝点击