IOS学习之UITableView表视图控件初步

来源:互联网 发布:软件平台性能指标 编辑:程序博客网 时间:2024/05/17 07:55

表视图这个控件学习的时候,发现是目前我接触到最复杂的组件。

在Android中也提供了类似表视图的控件叫ListView。

原生的ListView,支持的操作其实很有限,数据的条目展示,点击或是长按的操作。

后来慢慢的衍生出来的索引,分区,动态改变指定条目位置等。

到了IOS发现,原来都是这些设计概念全是从IOS的表视图移植过去的吧。

因此,IOS的表视图是个挺丰富的控件


以下文章内容我基本是这么个流程划分

最简单的表视图——》自定义Cell表——》可编辑表——》可动态移动表

以下是配合Navigation导航条控件演示的tableView各种实现。

一:基础表视图

我们看下表视图一个大致的界面模型

首先是navc的顶级视图


这个视图控制器的代码基本很前面提到的导航那章一样,只是多了一个数组容器来保存要显示的三个二级视图控制器

看下m文件

[cpp] view plaincopyprint?
  1. //   
  2. //  NonoFirstLevelViewController.m   
  3. //  NavTest   
  4. //   
  5. //  Created by Nono on 12-4-26.  
  6. //  Copyright (c) 2012年 NonoWithLilith. All rights reserved.  
  7. //   
  8.   
  9. #import "NonoFirstLevelViewController.h"  
  10. #import "NonoSecondLevelViewController.h"  
  11. #import "SimpleTableViewController.h"  
  12. #import "CustomCellViewController.h"   
  13. #import "EditViewController.h"  
  14. @interface NonoFirstLevelViewController ()  
  15.   
  16. @end  
  17.   
  18. @implementation NonoFirstLevelViewController  
  19. @synthesize controllers = _controllers;  
  20. #pragma 实现头文件中自定义方法;   
  21. - (void)initAllSecondControllers:(NSMutableArray *)array  
  22. {  
  23.     SimpleTableViewController *controller1 = [[SimpleTableViewController alloc] init];  
  24.     [controller1 setTitle:@"简单表视图"];  
  25.     [array addObject:controller1];  
  26.     [controller1 release];  
  27.       
  28.     CustomCellViewController *controller2 = [[CustomCellViewController alloc] init];  
  29.      [controller2 setTitle:@"自定义cell视图"];  
  30.     [array addObject:controller2];  
  31.     [controller2 release];  
  32.       
  33.       
  34.     EditViewController *controller3 = [[EditViewController alloc] init];  
  35.     [controller3 setTitle:@"可编辑视图"];  
  36.     [array addObject:controller3];  
  37.     [controller3 release];  
  38. }  
  39.   
  40. - (id)initWithStyle:(UITableViewStyle)style  
  41. {  
  42.     self = [super initWithStyle:style];  
  43.     if (self) {  
  44.     }  
  45.     return self;  
  46. }  
  47.   
  48. - (void)viewDidLoad  
  49. {  
  50.     [super viewDidLoad];  
  51.     self.title = @"表视图Demo";  
  52.     //实例化一个可变数组   
  53.     NSMutableArray *array = [[NSMutableArray alloc] init ];//  
  54.     self.controllers = array;  
  55.     [array release];  
  56.     [self initAllSecondControllers:self.controllers];  
  57. }  
  58.   
  59. - (void)viewDidUnload  
  60. {  
  61.     [super viewDidUnload];  
  62. }  
  63.   
  64. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
  65. {  
  66.     return (interfaceOrientation == UIInterfaceOrientationPortrait);  
  67. }  
  68.   
  69. #pragma mark - Table view data source  
  70. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
  71. {  
  72.     return [self.controllers count];  
  73. }  
  74.   
  75. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  76. {  
  77.     static NSString *CellIdentifier = @"FirstLevelCell";  
  78.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  79.     if (cell == nil) {  
  80.         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];  
  81.     }  
  82.     NSUInteger row = [indexPath row];  
  83.     NonoSecondLevelViewController *controller = [self.controllers objectAtIndex:row];  
  84.     cell.textLabel.text = [controller title];  
  85.     return cell;  
  86. }  
  87.   
  88. #pragma mark - Table view delegate   
  89. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  
  90. {  
  91.     NSUInteger row = [indexPath row];  
  92.     NonoSecondLevelViewController  *secondVC = [self.controllers objectAtIndex:row];  
  93.      [self.navigationController pushViewController:secondVC animated:YES];  
  94.        
  95. }  
  96.   
  97. @end  
顶视图类基本就是一个导航作用。

线面我么先看最简单的这条目

简单表视图:


[cpp] view plaincopyprint?
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  2. {  
  3.     //控件复用   
  4.     static NSString *CellIdentifier = @"simpleCell";  
  5.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  6.     if (cell == nil) {  
  7.         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];  
  8.         
  9.     }  
  10.     NSUInteger row = [indexPath row];  
  11.     NSString *string = [self.data objectAtIndex:row];  
  12.     cell.textLabel.text = string;  
  13.       
  14.     //这个可以定义item右端小图标显示风格,默认是none;   
  15.     //cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;  
  16.     [string release];  
  17.     return cell;  
  18. }  

这边主要说如下几点:

1》。控件得复用,这个和Android很像,因此我们在获取cell对象时,先从原来得复用队列里查找(更具指定的标记,这点也告诉我们,我们可以设置多个标记),

若没有,那就新建一个

2》。整个tableview的style分两种,一种就是顶级视图界面的那种: self.tableView.style = UITableViewStylePlain,另一种就是这个视图的风格:

self.tableView.style = UITableViewStyleGrouped

3》.对于每个item,单元格样式使用了3个不同的单元格元素。依次左边开始有个图标,中间就是一个label,右侧会有一个详情栏。

4》。同样的对于每个cell也是有样式风格的 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]

针对3,4设置后得某种效果如下:

左端可以自己敬爱个图标进去,黑体字就是文本label,灰色的是详细文本标签,小箭头图标是accessoryType

以下就是代码

[cpp] view plaincopyprint?
  1. static NSString *CellIdentifier = @"FirstLevelCell";  
  2. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  3. if (cell == nil) {  
  4.     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];  
  5. }  
  6. NSUInteger row = [indexPath row];  
  7. NonoSecondLevelViewController *controller = [self.controllers objectAtIndex:row];  
  8. cell.textLabel.text = [controller title];  
  9. cell.detailTextLabel.text = @"什么情况";  
  10. //这个可以定义item右端小图标显示风格,默认是none;   
  11. cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;  
  12. return cell;  
默认风格的cell是不能显示详情标签内容的。

其实很多效果,代码都走一边就看出来了,具体就自己改动下代码就ok了

二:自定义的Cell

自定义的cell,xib实现


基本没什么好说的,看下该类额控制器文件

[cpp] view plaincopyprint?
  1. //   
  2. //  CustomCellViewController.m   
  3. //  NavTest   
  4. //   
  5. //  Created by Nono on 12-5-4.  
  6. //  Copyright (c) 2012年 NonoWithLilith. All rights reserved.  
  7. //   
  8.   
  9. #import "CustomCellViewController.h"  
  10.   
  11. @interface CustomCellViewController ()  
  12.   
  13. @end  
  14. @implementation CustomCellViewController  
  15. @synthesize customCell = _customCell;  
  16. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  17. {  
  18.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  19.     if (self) {  
  20.         // Custom initialization   
  21.     }  
  22.     return self;  
  23. }  
  24.   
  25. - (void)viewDidLoad  
  26. {  
  27.     [super viewDidLoad];  
  28.     NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"陈凯",@"Nono",@"Lilith",@"窗前明月光",@"疑是地上霜",@"举头望明月",@"低头思故乡",@"锄禾日当午",@"汗滴禾下土",@"谁知盘中餐",@"粒粒皆幸苦",nil];  
  29.     self.data = array;  
  30.     [array release];  
  31.     // Do any additional setup after loading the view from its nib.  
  32. }  
  33.   
  34. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
  35. {  
  36.     return (interfaceOrientation == UIInterfaceOrientationPortrait);  
  37. }  
  38.   
  39.   
  40. #pragma mark_   
  41. #pragma 数据源方法   
  42. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
  43. {  
  44.     return [self.data count];  
  45.       
  46. }  
  47.   
  48. // Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:  
  49. // Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)  
  50.   
  51. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  52. {  
  53.       
  54.     static NSString *CellIdentifier = @"CustomCell";  
  55.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  56.     if (cell == nil) {  
  57.         NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];  
  58.         if([nib count] > 0){  
  59.             cell = self.customCell;  
  60.             cell.backgroundColor = [UIColor redColor];  
  61.         }else{  
  62.             NSLog(@"加载 nib文件失败");  
  63.         }  
  64.           
  65.     }  
  66.     NSUInteger row = [indexPath row];  
  67.     NSString *string = [self.data objectAtIndex:row];  
  68.     UILabel *customlabel =(UILabel*) [cell viewWithTag:11];  
  69.     customlabel.text = string;  
  70.     [string release];  
  71.     return cell;  
  72. }  
  73. @end  
提几个注意点:

1》。cell的xib文件得拥有者设置成该类,在该类得头文件中定义一个输出口。

2》 我们看到cell的xib文件有3个label视图我们能看到,其实还有一个没有title的label视图,也就我们要动态添加数据的那个视图,

在xib文件中需要给他设置一个tag,这样我们在代码里才能根据tag找出该对象(和Android中得id很像)。这边我定义了11,所以

 UILabel *customlabel =(UILabel*) [cellviewWithTag:11];

    customlabel.text = string;

3》。xib文件加载,我是根据书上得列子方法。根据应用的束来获取。

4》。哦,还有点就是 static NSString *CellIdentifier = @"CustomCell";。这个在xib文件得指定器中定义,因为原本我们新建一个cell是有个传入指定标签,
而现在这个新建一个cell说白了就是直接从xib中加载一个实例化了,那么指定器怎需要在xib中定义下。
对于cell简单的自定义就是这样。


三:可编辑的tableView(删除,添加,移动)

[cpp] view plaincopyprint?
  1. //   
  2. //  EditViewController.m   
  3. //  NavTest   
  4. //   
  5. //  Created by Nono on 12-5-4.  
  6. //  Copyright (c) 2012年 NonoWithLilith. All rights reserved.  
  7. //   
  8.   
  9. #import "EditViewController.h"  
  10.   
  11. @interface EditViewController ()  
  12.   
  13. @end  
  14.   
  15. @implementation EditViewController  
  16. @synthesize edittableView;  
  17. - (void)editButtonPressed:(id)sender  
  18. {     
  19.     [self.edittableView setEditing:!self.edittableView.editing animated:(YES)];  
  20.     if (edittableView.editing) {  
  21.         [self.navigationItem.rightBarButtonItem setTitle:@"完成"];  
  22.     }else {  
  23.         [self.navigationItem.rightBarButtonItem setTitle:@"编辑"];  
  24.     };  
  25.     NSLog(@"点击了按钮");  
  26. }  
  27. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  28. {  
  29.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  30.     if (self) {  
  31.         // Custom initialization  
  32.     }  
  33.     return self;  
  34. }  
  35.   
  36. - (void)viewDidLoad  
  37. {  
  38.     [super viewDidLoad];  
  39.     NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"陈凯",@"Nono",@"Lilith",@"窗前明月光",@"疑是地上霜",@"举头望明月",@"低头思故乡",@"锄禾日当午",@"汗滴禾下土",@"谁知盘中餐",@"粒粒皆幸苦",nil];  
  40.     self.data = array;  
  41.     [array release];  
  42.     UIBarButtonItem *rigthButton = [[UIBarButtonItem alloc]  initWithTitle:@"编辑"  style:UIBarButtonItemStyleBordered  target:self  action:@selector(editButtonPressed:)];  
  43.     self.navigationItem.rightBarButtonItem = rigthButton;  
  44.     //self.navigationItem.prompt = @"加载";   
  45.     [rigthButton release];   
  46.     // Do any additional setup after loading the view from its nib.  
  47. }  
  48.   
  49. - (void)viewDidUnload  
  50. {  
  51.     [super viewDidUnload];  
  52.     // Release any retained subviews of the main view.  
  53.     // e.g. self.myOutlet = nil;  
  54. }  
  55.   
  56. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
  57. {  
  58.     return (interfaceOrientation == UIInterfaceOrientationPortrait);  
  59. }  
  60.   
  61. #pragma mark - Table view data source  
  62.   
  63. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
  64. {  
  65.     // Return the number of rows in the section.  
  66.     return [self.data count];  
  67. }  
  68.   
  69. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  70. {  
  71.     static NSString *CellIdentifier = @"editLevelCell";  
  72.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  73.     if (cell == nil) {  
  74.         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];  
  75.     }  
  76.     NSUInteger row = [indexPath row];  
  77.     NSString *string = [self.data objectAtIndex:row];  
  78.     cell.textLabel.text = string;  
  79.     [string release];  
  80.     return cell;  
  81. }  
  82.   
  83. #pragma 实现数据源协议中一些关于编辑操作方法  
  84. - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath  
  85. {  
  86.     //是否可以编辑,即是tableView setEditing的前提;默认是yes,实现这个方法估计主要是选择性的编辑条目。  
  87.     return YES;  
  88. }  
  89.   
  90. - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath  
  91. {  
  92.     //同理默认其实就是yes,移动模式(会显示可以触摸得移动button)必须是在实现了下面这个方法才有效,否则及时yes了,移动模式条也是不显示的,简单的说,你不能执行移动操作  
  93.     return YES;  
  94. }  
  95. //移动操作   
  96. - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath  
  97. {  
  98.     //拖动得思路就是先备份选中行,删除原来那份,将备份的一份插入到目标行   
  99.     NSUInteger fromRow = [sourceIndexPath row];  
  100.     NSUInteger toRow = [destinationIndexPath row];  
  101.     id ob = [[self.data objectAtIndex:fromRow] retain];  
  102.     [self.data removeObjectAtIndex:fromRow];  
  103.     [self.data insertObject:ob atIndex:toRow];  
  104.     [ob release];  
  105. }  
  106.   
  107. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath  
  108. {  
  109.       NSUInteger row = [indexPath row];  
  110.     //提交操作完的编辑   
  111.     if (editingStyle == UITableViewCellEditingStyleDelete) {  
  112.         [self.data removeObjectAtIndex:row]; //删除操作  
  113.         [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];  
  114.     }  
  115.       
  116.     if (editingStyle == UITableViewCellEditingStyleInsert) {  
  117.         [self.data insertObject:@"插入数据" atIndex:row];//插入操作  
  118.         [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];  
  119.     }   
  120. }  
  121.   
  122. #pragma 实现tableView委托中一些方法   
  123. - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;  
  124. {  
  125.     //设置可编辑得样式:系统提供了三种,一种是删除,一种是插入,一种时是none  
  126.     NSInteger row = [indexPath row];  
  127.     if(row %2 == 0)//这边做了小处理,间隔显示删除和插入  
  128.     {  
  129.         return UITableViewCellEditingStyleDelete;  
  130.     }  
  131.     return UITableViewCellEditingStyleInsert;  
  132. }  
  133. @end  
基本代码如上。
原创粉丝点击