Presentation is loading. Please wait.

Presentation is loading. Please wait.

Http://www.xs360.cn 《IOS应用开发教程》 QQ学习群:262779381.

Similar presentations


Presentation on theme: "Http://www.xs360.cn 《IOS应用开发教程》 QQ学习群:262779381."— Presentation transcript:

1 《IOS应用开发教程》 QQ学习群:

2 第六章 IOS高级界面编程 QQ学习群:

3 1.掌握IOS中UIImageView图片视图的方法及使用。 2.掌握UITableView的重用机制。
教学目标: 1.掌握IOS中UIImageView图片视图的方法及使用。 2.掌握UITableView的重用机制。 3.掌握UITableView的使用方法。 QQ学习群:

4 6.1UIImageView图片控件 在前面的章节中,我们使用过UIImage来加载图片,而UIImageView 是用来在屏幕上显示图片的一个视图,如要使用UIImageView来显示 图片,首先要将图片文件加载到UIImage上,然后通过一些方法去使 用UIImage。系统为我们提供了四种常用加载UIImage的方法。 ·imageNamed:通过项目中的文件来创建。 ·imageWithCGImage:通过Quartz 2D对象创建。 ·imageWithContentsOfFile:通过指定路径创建。 ·imageWithData:通过NSData创建。 QQ学习群:

5 2.[self.view addSubview:ImageView]; 3.[ImageView release];
我们介绍如何用这几种方法在UIImageView中显示图片。首先还是要初始化一个UIImageView视图的实例,并将实例添加到窗口上。还是新建一个Single View Application项目模板,在ViewController.m文件中添加下列代码。 1.UIImageView *ImageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 200, 150, 150)]; 2.[self.view addSubview:ImageView]; 3.[ImageView release]; 然后再设置UIImageView的图片就能在视图上显示图片了。记住要将图片文件导入到项目中。 QQ学习群:

6 1. //---------------第一种设置图片方法---------------//
2. [ImageView setImage:[UIImage 3. // 第二种设置图片方法 // 4. NSString *filePath=[[NSBundle mainBundle] 5. UIImage *images=[UIImage imageWithContentsOfFile:filePath]; 7. [ImageView setImage:images]; 8. // 第三种设置图片方法 // 9. NSString *filePath=[[NSBundle mainBundle] 10. 11. NSData *data=[NSData dataWithContentsOfFile:filePath]; 12. UIImage *image=[UIImage imageWithData:data]; 13. [ImageView setImage:image]; QQ学习群:

7 那有的读者就会有疑问,第一种方法这么简单,代码又少,为什么还要用其他 几种方法?确实第一种方法是最简单的,这几种方法都各有优势和劣势。 比如第一种方法(imageNamed),当使用这种方法时,系统会把图像文件 缓存到内存中,那么当图像文件较大,或者图像较多的时候,就会消耗大量的 内存,我们也知道IOS系统对内存的要求是很高的,一不小心就会造成内存的 错误导致系统的崩溃。但它的优点也很明显,当项目中需要复用该图像文件时 ,系统就会从缓存中直接读取该文件,节省内存空间。 当使用imageWithData方法时,系统会将图像文件以数据的形式加载到应用 程序中,如果你的图像文件不需要复用,或者文件比较大时尽力使用 imageWithData方法。 下面介绍UIImageView常用的属性。 ·Image:设置UIImageView视图中正常状态下显示的图片。 ·highlightedImage:设置UIImageView视图在高亮状态下显示的图片。 ·isUserInteractionEnabled:设置是否允许用户交互。 QQ学习群:

8 在本章前面的小节中我们介绍过,IOS组件有4中状态,正常,高亮,选中 和禁用。在UIImageView中如要设置视图在高亮状态下的图片,则要设置 highlighted属性为YES,才能在高亮状态下显示图片,这一点也是要特别 注意的。 isUserInteractionEnabled属性也是比较重要的,我们通过一个例子来理 解该属性的作用。我们在本小节例子的基础上进行修改。我们将设置的图 片删除,并将UIImageView视图的背景色设置为cyanColor。 17.UIImageView *ImageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 200, 150, 150)]; 18.ImageView.backgroundColor = [UIColor cyanColor]; 19.[self.view addSubview:ImageView]; 20.[ImageView release]; QQ学习群:

9 因为UIImageView也是继承与UIView,所以也可以在UIImageView上添加 子视图,我们在视图上添加一个按钮,用来完成用户交互功能,比如在用户设 置头像时,可以单击按钮,更换用户喜爱的图像。 21.UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 22.button.frame = CGRectMake(25, 50, 100, 40); 23.[button forState:UIControlStateNormal]; 24.[ImageView addSubview:button]; 创建好UIButton的实例后,要将实例添加到UIImageView视图上,作为它的 子视图。那么在设置button的frame值时要注意,此时的坐标是以它的父类坐 标系统为基准,设置的时候要注意XY的位置。 如果去单击按钮,可以发现无法单击按钮,这是因为前面所提到的一个重要属 性,isUserInteractionEnabled没有设置,它的默认值是NO,所以我们要将 它设置为YES,这样就可以点击按钮了。读者可以自己实现按钮的相关事件。 QQ学习群:

10 系统还为UIImageView提供了幻灯片播放的功能,通过设置先关的属性可以 达到幻灯片播放的效果。我们通过一个例子来学习如何设置相关属性让图片“动” 起来。 新建一个Single View Application项目模板,同样是在ViewController.m文 件中的viewDidLoad方法中添加下列代码。 1.UIImage *image1 = [UIImage 2.UIImage *image2 = [UIImage 3.UIImage *image3 = [UIImage 4.UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(50, 50, 300, 200)]; 5.imageView.animationImages = [NSArray 6.arrayWithObjects:image1,image2,image3, nil]; 7.imageView.animationDuration = 5; 8.[imageView startAnimating]; 9.[self.view addSubview:imageView]; 10.[imageView release]; QQ学习群:

11 首先创建3个UIImage类的实例并初始化图片文件,然后创 建一个UIImageView的实例用于显示图片,UIImageView中 提供了一个animationImages属性用于设置图片的动画效果 ,然后创建一个数组存储前面创建的3个UIImage类的实例, animationDuration属性设置图片切换的时间间隔,设置玩相 关属性后,通过starAnimation方法使得图片开始“动”起来。 别忘了释放掉内存。 [imageView release]; 关于UIimageView视图动画的方法有2个,startAnimation 和stopAnimation,用于开始和停止动画,还有一个BOOL类 型的标识符,用于标识UIImageView的实例是否处于运动的 状态,以便于做出相应的判断。 本小节介绍了UIImageView视图相关属性和方法的使用,还 介绍了简单地动画实现,我们可以用图片视图实现很多漂亮的 动画效果。更多地动画内容会在第九章动画实现中详细介绍。 QQ学习群:

12 6.2UITableView表视图控件 QQ学习群:262779381
UITableView是iPhone应用的最为广泛的一个类,或者说一个控件。它主要是用于 显示文本内容或者用于内容的编辑。比如在iPhone的设置中,这些内容都是显示在 UITableView中,如图所示。 QQ学习群:

13 那么为什么UITableView这个控件会用的如此广泛呢?它有什么 优点呢?每一个App都会有大量的数据需要显示,比如新浪微博, 关于新闻的App,它们都有很多的信息内容,虽然内容很多,但是 它们的组成结构是一些样的。所以我们就可以根据一些条件进行分 组,这种情况正是适合了UITableView控件充分发挥其作用,它提 供了分组功能,并能够对相关信息进行编辑。 而且UITableView的功能非常强大,其中最大的优点就是单元格 重用机制,比如你有10000条信息要显示,它并不需要创建10000 个相应的单元格cell,只会先创建屏幕上能显示cell条数的单元格, 当你下拉的时候,系统会重用显示不到的单元格,以提高系统的工 作效率。 QQ学习群:

14 6.2.1UITableView的创建 在本小节中,我们将来学习如何创建一个表视图,并在表视图中显示相应的信 息。在学习如何创建之前,我们首先来了解一下表视图中相关的概念及其表视 图的一个整体结构。 在表视图中,系统提供了2中样式,一种是UITableViewStylePlain,另一 种则是UITableViewStyleGrouped,我们来看一下苹果官方的一个表视图的 图示,如图所示。 QQ学习群:

15 上图中前两种类型都是UITableViewStylePlain类型,最后一种类型则是 UITableViewStyleGrouped,它是一个带有分组功能的表视图。那么我们就知道了在 设置中的表视图都是UITableViewStyleGrouped分组类型的表视图。 每一个表视图都是由3个部分组成,tableHeaderView头视图,TableView正文部分和 tableFooterView尾视图,头视图和尾视图是用来显示一些辅助的信息,比如在图11-2 中第2个表视图中的头视图就是“A”,尾视图没有进行设置。头视图和尾视图都可以是缺 省的。我们注意到在每个单元格的右侧有一串的字母,它的作用是方便用户快速选择首 字母名称的索引功能,类似于我们在iPhone中常用到的联系人操作。我们在后面的内容 中也会学习到如何为表视图创建一个索引功能。 在表示图中每一行用于显示内容的部分叫做单元格Cell,每一个Cell也是由3个部分组成, 头视图CellHeaderView,内容部分和尾视图CellFooterView,和表视图一样,单元格 头视图和尾视图是用来显示一些辅助的信息,它可以为空。在第2种类型 UITableViewStyleGrouped中,就和Plain类型不同,它是由多个Section组成,每个 Section中又由多个单元格Cell组成,我们可以从图中很清楚的看到分组的情况。而每个 Section也是由头视图,一连串单元格和尾视图组成,我们可以通过代理方法来设置它的 头视图和尾视图,在后面的内容中我们也会提到。 QQ学习群:

16 · Plain类型表视图的创建 在介绍完相关概念之后,我们就来学习如何创建一个UITableView 表视图。在XCode中新建一个Single View Application项目模板。 在ViewController.m文件的viewDidLoad方法中初始化 UITableView表视图实例 ViewController.m文件中创建我们TableView表视图。在这之前我们 还要在ViewController.h文件中创建一个NSMutableArray的全局的 实例,这样便于在文件中访问。还有很重要的一点,UITableView和其 他的类有所不同,它必须实现两个代理方法,所以在头文件中要引入两 个和UITableView相关的协议。我们会对这个2个协议进行详细的解释。 QQ学习群:

17 1. #import <UIKit/UIKit. h> 2
1.#import <UIKit/UIKit.h> ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate> 3.{ 4. NSMutableArray *listofFile; 5.} 7.- (void)viewDidLoad 8.{ 9. [super viewDidLoad]; 10. UITableView *tableView = [[UITableView alloc]initWithFrame:[UIScreen 11. mainScreen].applicationFrame style:UITableViewStylePlain]; 12. [tableView setDataSource:self]; 13. [tableView setDelegate:self]; 14. listofFile = [[NSMutableArray alloc]init]; 15. [listofFile 16. [listofFile 17. [listofFile 18. [listofFile 19. [listofFile 20. [listofFile 21. [listofFile 22. [listofFile 23. [self.view addSubview:tableView]; 24. [tableView release]; 25.} QQ学习群:

18 这里关键的代码是设置代理,然后将需要显示的数据添加到数组中,并在代理 方法中实现在表视图中显示内容的功能。 26
这里关键的代码是设置代理,然后将需要显示的数据添加到数组中,并在代理 方法中实现在表视图中显示内容的功能。 26.- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 27.{ 28. return [listofFile count]; 29.} 这个代理方法比较好理解,它是返回每个Section中的单元格cell的数目,一般 情况下是以数组的形式表示section中的行数,例如使用数组的count属性 [Array count],这里我们就使用我们定义好的可变数组元素的个数作为cell的 行数。 QQ学习群:

19 30. - (UITableViewCell. )tableView:(UITableView
30.- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 31.{ 32. static NSString *CellIdentifier 33. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 34. if(cell == nil){ 35. cell = [[[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleDefault) 36. reuseIdentifier:CellIdentifier]autorelease]; 37. } 38. NSString *cellValue = [listofFile objectAtIndex:indexPath.row]; 39. cell.textLabel.text = cellValue; 40. return cell; 41.} 这个代理方法可以比较难理解,它主要的意思就是告诉UITableView我们表视图中所要显示的具体的内容 是什么,更具体的来说,是第几组第几条数据的具体内容是什么。在TableView中每填充一个单元格的数 据就会触发一次该代理方法。我们首先定义了一个单元格标识符字符串,作为后面单元格重用的判断标识 。 QQ学习群:

20 重用UITableViewCell对象机制的原理是这样的,因为IOS设备特别是iPhone设备的内 存是有限的,假设我们要在表视图上显示的内容很多,那么就要相应地创建很多的 UITableViewCell对象,这样的话,会造成IOS设备的内存耗尽,导致系统的崩溃。但我 们在使用UITableView时可以发现,显示的Cell数量是有限的而且是固定的,而其他的 UITableViewCell对象会移出窗口,这样UITableView对象就会将窗口外的 UITableViewCell对象放入UITableViewCell对象池中,用于单元格的重用。当 UITableView对象要求数据源返回一个UITableViewCell对象时,数据源DataSource就 会查看对象池。如果有未使用的UITableViewCell对象,数据源就会用重新配置这个对 象,用于显示新的内容。这样的话就能有效的减少创建UITableViewCell对象的数量。 我们可以从图中直观的看到UITableViewCell对象重用的过程。 QQ学习群:

21 if(cell == nil){ cell = [[[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:CellIdentifier]autorelease]; 这部分代码的意思是判断UITableViewCell对象是否被重用,如果没有 的话,就会创建一个新的单元格。 在对单元格重用时会出现另一个问题,因为UITableView继承于 UIScrollView,而UIScrollView继承于UIView,那么就是说UITableView 可以子类化各种类型的视图,这样问题就出现了,UITableView对象就可能 拥有不同类型的UITableViewCell对象。那么在对象池中有很多种不同类型 的对象,那么怎样对单元格进行重用才能保证类型一致呢? 每一个UITableViewCell对象都有一个reuseIdentifier属性,它的类型是 NSString。通过向表格视图传入特定的NSString对象,我们这里就定义了 一个NSString类型的数据Identifier,那么这样数据源就可以查询并获取一 个可重用的UITableViewCell对象,通过reuseIdentifier属性来判断二者的 类型是否一致。这样这个问题就得到了解决。 QQ学习群:

22 程序中这两句代码读者可能会有点疑惑,这两个代理 是什么意思呢? [tableView setDataSource:self]; [tableView setDelegate:self]; DataSource是UITableViewDataSource类型数据 ,它主要是为UITableView提供显示的数据,指定 UITableViewCell支持的编辑操作类型,比如插入, 删除和重新排列,并且它会根据用户的操作来更新表 视图中数据。 Delegate是UITableViewDelegate类型数据,它主 要提供一些可选的方法,用来控制tableView的选择 ,指定section和头视图尾视图的显示,以及协助完成 cell单元格的删除重排序等功能。 QQ学习群:

23 ·Group类型表视图的创建 上小节中我们介绍了Plain类型表视图的创建,那么本小节内容将介绍另一种 类型的表视图的创建。Group类型的表视图的创建和Plain类型的创建还是有很 多的不同的,因为它多了一个对section属性的设置。下面我们就来一起来学习 创建的方法。 在Group类型表视图创建时,我们另外又添加了2个代理方法,用于显示设置 section区域的个数和section的HeaderView以及FooterView。 在XCode中新建一个Single View Application项目模板,和Plain类型表视 图创建一样,在viewDidLoad方法中创建实例。 别忘了在ViewController.h文 件中添加2个协议。 QQ学习群:

24 1. #import <UIKit/UIKit. h> 2
1.#import <UIKit/UIKit.h> ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource> 4.- (void)viewDidLoad 5.{ 6. [super viewDidLoad]; 7. UITableView *tableView = [[UITableView alloc]initWithFrame:[UIScreen mainScreen].bounds 8. style:UITableViewStyleGrouped]; 9. [tableView setDataSource:self]; 10. [tableView setDelegate:self]; 11. self.view = tableView; 12. [tableView release]; 13.} QQ学习群:

25 在创建实例时,我们只需创建一个空的表视图,也不需要通过数组来添加信息 。我们将在相应的代理方法中添加表中的信息。这里还是要将代理和数据源设置 为由表视图的实例来管理。最后释放相应实例的内存。 接下来我们在代理方法中设置section区域的个数。 14.- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 15.{ 16. return 3; 17.} 这个代理方法很好理解,它设置了表视图中section的个数为3。在设置完 section属性的值后,即确定了分组的个数之后,我们就可以再定义每个section 里单元格cell的个数。在代理方法tableView numberOfRowsInSection中设 置。 QQ学习群:

26 18. - (NSInteger) tableView:(UITableView
18.- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 19.{ 20. if(section == 1 || section == 2){ 21. return 2; 22. } 23. return 1; 24.} 这里我们将section1和section2中的cell值设置为2,而section0中的cell单元 格个数为1。设置完表格视图的具体格式之后,我们就可以向表格视图中添加内 容了。我们这里的添加方法和plain类型的添加方法有点不同,通过section属性 和indexPath中的row属性定位到要添加内容的指定位置,而不是添加到数组中 统一显示了。 QQ学习群:

27 25. - (UITableViewCell. )tableView:(UITableView
25.- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 26.{ 27. int section = indexPath.section; 28. int row = indexPath.row; 29. static NSString *CellIdentifier 30. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 31. if(cell == nil){ 32. cell = [[[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleDefault) 33. reuseIdentifier:CellIdentifier]autorelease]; 34. switch (section) { 35. case 0:cell.textLabel.text 36. break; 37. case 1: 38. if(row ==0) 39. { 40. cell.textLabel.text 41. }else{ 42. cell.textLabel.text 43. } 44. break; 45. case 2: 46. if(row == 0) 47. { 48. cell.textLabel.text 49. }else{ 50. cell.textLabel.text 51. } 52. } 53. } 54. return cell; 55.} QQ学习群:

28 定义标识符和单元格重用的方法和前面plain类型的表视 图一致,在添加内容时,我们使用了一个switch语句, 来选择每个section中的cell,从而将内容添加到准确的 位置。最后,还要返回cell单元格,如果不返回相应的 对象,内容将不会显示在表视图中。 int section = indexPath.section; int row = indexPath.row; 在这两行代码中,有一个indexPath属性,它主要用 于标识当前cell在表视图中的位置,他还有2个属性, section和row,前者代表当前cell处于第几个section 中,而后者则表示当前cell在section中的第几行。通过 这两个属性用户就可以定位到指定的cell而进行相关的 操作了。 QQ学习群:

29 我们通常在iPhone应用中看到Group样式的表视图中每个section前面会有一段 文字,用于解释或者分类该section,这个是我们前面提到的组成表视图的3个 部分里地tableHeaderView,我们可以通过相应的代理方法来添加 HeaderView视图,同样地,也可以添加tableFooterView视图。 56.- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 57.{ switch (section) { case 0: case 1: case 2: default: return 0; } 64.} 65.- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section 66.{ switch (section) { case 0: 1"; case 1: 2"; case 2: 3"; default:return 0; } 73.} QQ学习群:

30 在这两个代理方法中,通过switch语句为每一个 section分别添加一个HeaderView头视图和一个 FooterView尾视图。这些代理方法都不要刻意的去记 ,只须了解含义,我们可以通过SDK来了解 UITableView类中有哪些代理方法,然后通过相应的 方法去实现。 QQ学习群:

31 6.2.2UITableView相关属性的使用 在本小节内容中,我们将一起来学习UITableView类中一些属性的使用方法。 包括对文本内容字体颜色、分割线的样式颜色以及表视图的等等,通过这些属 性的设置,能让你的表视图更加的美观。 ·表视图tableView相关属性 首先我们来设置cell单元格中内容的属性,我们在6.2.1小节的例子的基础 上进行修改。在tableView cellForRowAtIndexPath方法中修改cell单元格中 的textLabel属性。 1.- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 2.{ 3. /……/ 4. NSString *cellValue = [listofFile objectAtIndex:indexPath.row]; 5. cell.textLabel.text = cellValue; 6. cell.textLabel.font = [UIFont size:20]; 7. cell.textLabel.textColor = [UIColor redColor]; 8. return cell; 9.} QQ学习群:

32 因为在设置字体时,中文支持不是很完善,所以 我们将代码实例中表视图内容里的中文内容改成 了英文内容,这样可以清楚的看到字体改变的情 况。构建并运行,可以看到cell中的内容有了变化 ,如图所示。
QQ学习群:

33 我们还可以自定义表视图每个单元格的高度,还可以为表视图添加背景图片。我 们在viewDidLoad方法中对表视图进行相关属性的设置。
10.- (void)viewDidLoad 11.{ [super viewDidLoad]; UITableView *tableView = [[UITableView alloc]initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain]; [tableView setDataSource:self]; [tableView setDelegate:self]; listofFile = [[NSMutableArray alloc]init]; [listofFile [listofFile [listofFile [listofFile [listofFile [listofFile [listofFile [listofFile QQ学习群:

34 26. self. view = tableView; 27. tableView. rowHeight = 100; 28
26. self.view = tableView; 27. tableView.rowHeight = 100; 28. UIImageView *backgoundView = [[UIImageView alloc]initWithFrame: 29. [UIScreen mainScreen].applicationFrame]; 30. backgoundView.image = [UIImage 31. tableView.backgroundColor = [UIColor purpleColor]; 32. tableView.backgroundView = backgoundView; 33. [backgoundView release]; 34. [tableView release]; 35.} QQ学习群:

35 这里我们首先修改了每行单元格中的内容,然后将每行单元格的高度设置为100 ,默认值是44px。接下来就要为表视图添加背景,一种方法就是直接通过改变背 景的颜色,而另一中则是创建一个图片视图,然后将tableView的 backgroundView属性设置图片视图的实例。这里需要注意的是,如果同时设置 这两个属性,就像我们在代码中写的那样,那么对背景设置的颜色就会失去效果 ,只会显示图片视图。在backgroundView属性上按住Command键然后左键单 击,查看它的SDK,可以看到系统对backgroundView属性进行了retain操作, 所以使用完之后,我们还要对图片视图进行释放。 QQ学习群:

36 最后,我们还可以设置表视图中分割线Separator的属性,系统为我们提供了 三种类型的分割线:
UITableViewCellSeparatorStyleNone, UITableViewCellSeparatorStyleSingleLine, UITableViewCellSeparatorStyleSingleLineEtched 最后一种类型只能用在Group类型的表视图中使用,使用第一种类型会让分割 线消失。我们还可以设置分割线的颜色。下面我们就将分割线的颜色也设置为 红色。 36.- (void)viewDidLoad 37.{ [super viewDidLoad]; /……/ backgoundView.image = [UIImage tableView.backgroundView = backgoundView; [backgoundView release]; tableView.backgroundColor = [UIColor purpleColor]; tableView.separatorColor = [UIColor redColor]; tableView release]; 50.} QQ学习群:

37 ·UITableViewCell单元格相关属性 其实每一个UITableViewCell单元格除了HeaderView和FooterView两个视 图之外,还有2个视图,imageView和accessoryView(辅助图标视图),结构 如图所示。 QQ学习群:

38 UITableViewCellAccessoryDisclosureIndicator
系统也为我们提供了三种辅助图标视图,我们在下表中列出了这三种辅助图标视 图。 辅助图标名称 辅助图标样式 UITableViewCellAccessoryDisclosureIndicator UITableViewCellAccessoryDetailDisclosureButton UITableViewCellAccessoryCheckmark QQ学习群:

39 接下来我们通过一个switch语句分别为表视图中前三个单元格添加这三种类型 的辅助图标。在这之前,为了便于读者的阅读,我们将cell单元格的高度还原为 默认值44px,将表视图的背景设置为白色。
1.- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 2.{ 3. int row = indexPath.row; 4. static NSString *CellIdentifier 5. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 6. if(cell == nil){ cell = [[[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleDefault) 8. reuseIdentifier:CellIdentifier]autorelease]; 9. } NSString *cellValue = [listofFile objectAtIndex:indexPath.row]; cell.textLabel.text = cellValue; cell.textLabel.font = [UIFont size:20]; cell.textLabel.textColor = [UIColor redColor]; QQ学习群:

40 14. switch (row) { 15. case 0: 16. cell
14. switch (row) { 15. case 0: 16. cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;break; 17. case 1: 18. cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;bre ak; 19. case 2: 20. cell.accessoryType = UITableViewCellAccessoryCheckmark;break; 21. default: 22. break; 23. } 24. return cell; 25.} QQ学习群:

41 同样的,我们还要为单元格添加图片视图,这样的话,自定义单元格的2个视图 就添加完成了。
cell.textLabel.font = [UIFont size:20]; cell.textLabel.textColor = [UIColor redColor]; switch (row) { case 0: cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cell.imageView.image = [UIImage case 1: cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; cell.imageView.image = [UIImage case 2: cell.accessoryType = UITableViewCellAccessoryCheckmark; cell.imageView.image = [UIImage default: break; } 41.return cell; QQ学习群:

42 构建并运行,可以看到添加了图片的单元格效果如图 所示。 细心的读者可能会发现,在三种辅助图标视图中, DetailDisclosureButton类型的辅助图标点击会出现 按钮的效果,而其他的两种图标则不会出现。对,其实 这一种图标也可以说是一种按钮,那么我们该如何实现 这个点击事件呢? QQ学习群:

43 是不是在定义的时候就写单击事件呢?如果是这样,那么如何获取到这个按钮呢?我们并没有定义这个实例,只是在定义单元格时设置了辅助图标视图。其实要实现这个按钮的单击事件,是通过一个代理方法实现的,方法中有一个indexPath参数,用于设置特定单元格的辅助图标。下面我们就为这个按钮实现一个单击事件,点击按钮之后,会弹出一个对话框,并显示当前单元格的相关信息。 42.- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath 43.{ UIAlertView *alertView = [[UIAlertView is United Kingdom" delegate:self otherButtonTitles:nil]; [alertView show]; [alertView release]; 48.} QQ学习群:

44 因为在设置单元格辅助图标视图时,我们仅仅 设置了一个DetailDisclosureButton类型的图 标,所以我们在代理方法中并没有通过 indexPath属性来定位到特定的单元格上。那 么假如在表视图中有2个或2个以上辅助图标类 型为DetailDisclosureButton时,那么要实现 相关的按钮单击事件该如何实现呢?这个效果 希望读者能够自己完成。 QQ学习群:

45 下面我们来一起学习单元格添加文本的样式,系统也为我们提供了4中类型的单 元格形式,其效果如图所示。
QQ学习群:

46 这四种类型依次是: UITableViewCellStyleSubtitle:单元格中支持小文本(detailTextLabel)的显 示。 UITableViewCellStyleDefault:系统默认的类型,不支持其他文本的显示。 UITableViewCellStyleValue1:单元格也支持小文本,和第一种类型不同,文 本和小文本分居单元格的左右两侧。 UITableViewCellStyleValue2:单元格支持小文本,文本和小文本都在单元格 左侧。 QQ学习群:

47 在单元格中有一个detailTextLabel属性,可以设置小文本内容,这里要注意的 就是如果你设置了detailTextLabel属性,但是UITableViewCellStyle设置的还 是UITableViewCellStyleDefault时,系统是不会显示你所设置的小文本内容。 我们下面在例子中对单元格类型进行相应的设置。我们将表视图单元格的类型设 置为UITableViewCellStyleSubtitle,然后再设置detailTextLabel中的内容, 最后分别为3个单元格添加详细小文本内容。 cell = [[UITableViewCell alloc]initWithStyle: (UITableViewCellStyleSubtitle)reuseIdentifier:CellIdentifier]; 51.case 0: cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cell.detailTextLabel.text Capital is Washington, D.C."; cell.imageView.image = [UIImage 55.case 1: cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; cell.detailTextLabel.text Capital is London"; cell.imageView.image = [UIImage 59.case 2: cell.accessoryType = UITableViewCellAccessoryCheckmark; cell.detailTextLabel.text Capital is Paris"; cell.imageView.image = [UIImage QQ学习群:

48 构建并运行,可以看到单元格中多了一行小文本文字,用于对文本内容解释说明 ,效果如图所示。
QQ学习群:

49 6.2.3表视图的编辑模式 在iPhone使用到表视图的应用中,比如电话中的联系人表视图,都可以对联系 人内容进行编辑,比如添加,删除,重新排列顺序等等,那么接下来这一小节我 们就来一起学习如何对表视图进行编辑。 ·删除单元格记录 对比上小节例子最后的效果,发现视图中多了一个导航栏,所以我们先要添 加一个导航栏控制器的实例。在AppDelegate.m文件中添加下列代码。 1.*)launchOptions { 2. // Override point for customization after application launch. 3. ViewController *vc = [[ViewController alloc]init]; 4. UINavigationController *navi = [[UINavigationController alloc]initWithRootViewController:vc]; 5. self.window.rootViewController = navi; 6. return YES; 7.} QQ学习群:

50 这三行代码的含义首先创建ViewController的实例,然后创建一个 UINavigationController的实例,并将根视图设置为ViewController的实例, 最后设置window的根视图控制器为UINavigationController的实例。 因为我们在编辑模式中需要多次使用到UITableView的实例,所以我们在 ViewController.h文件中将实例定义为全局变量。 8.#import <UIKit/UIKit.h> ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource> 10.{ 11. NSMutableArray *listofFile; 12. UITableView *_tableView; 13.} 15.self.title QQ学习群:

51 接下来我们就可以开始编辑模式的设置了,在设置之前,我们将前三行单元格中 添加的图片视图和辅助图标还有小文本内容删除,便于更直观的观察编辑模式。 首先我们要通过一个方法来开启表视图的编辑功能。 16.- (void)setEditing:(BOOL)editing animated:(BOOL)animated 17.{ 18. if(_tableView.editing){ 19. [_tableView setEditing:NO animated:YES]; 20. }else{ 21. [_tableView setEditing:YES animated:YES]; 22. } 23.} QQ学习群:

52 通过这个方法,就可以将表视图置于编辑模式中,方法中的if……else语句的含 义是如果当前表视图处于编辑状态下,就不能让它进入编辑模式;而如果当前表 视图不是出于编辑模式时,当点击编辑按钮时,就会让表视图进入编辑模式。 我们在UINavigationController导航栏控制器这一章中介绍过在 navigationItem中有一个editButtonItem按钮专门适用于表视图的编辑模式 ,我们在viewDidLoad方法中将editButtonItem添加到导航栏控制器的右侧按 钮上。 24.- (void)viewDidLoad 25.{ 26. [super viewDidLoad]; 27. /……/ 28. _tableView.separatorColor = [UIColor redColor]; 29. [_tableView release]; 30. self.navigationItem.rightBarButtonItem = self.editButtonItem; 31.} QQ学习群:

53 可以看到,现在表视图已经支持对单元格的编辑了,我们接下来只需要在相关的 代理方法中实现对应的增、删、改方法即可。首先我们实现对表视图中单元格内 容的删除功能。 32.- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 33.{ 34. return YES; 35.} 36.- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 37.{ 38. [listofFile removeObjectAtIndex:indexPath.row]; 39. [_tableView 40. withRowAnimation:UITableViewRowAnimationFade]; 41.} QQ学习群:

54 我们来观察这两个实现表视图单元格删除功能的代理方法,第一个BOOL类型 的方法,它的作用是让用户做出判断,当前表视图是否能对单元格进行编辑,返 回YES代表能进行编辑,相反,NO代表不能对单元格进行编辑。而实现删除功 能的其实是第二个代理方法,它的几个参数分别是代表表视图实例、表视图编辑 模式类型和在indexPath中的行数。 要从一个表视图中删除一行数据,要分为两步: 1.从数组中移除相应的数据内容; 2.在表视图中删除相应的数据内容。 可能有些读者会对[_tableView 部分代码产生疑惑。 思考:我们存储数据的数组不是[listlofFile]吗?那为什么删除数组是 indexPath? QQ学习群:

55 我们可以尝试一下用listofFile数组代替indexPath,然后我们在运行程序,单击 edit按钮,删除时会发现程序崩溃了,这是因为其实我们在删除表视图中记录时 ,是通过indexPath.row这个属性进行操作,而不是通过装在数据的数组。我们 打开SDK看一下这个代理方法可以发现,在方法中已经为我们写好了参数,就是 indexPath数组。 最后一个参数withRowAnimation代表了改变单元格时的动画效果,系统为 我们提供了8中类型的动画效果。分别是: UITableViewRowAnimationFade UITableViewRowAnimationRight UITableViewRowAnimationLeft UITableViewRowAnimationTop UITableViewRowAnimationBottom UITableViewRowAnimationNone UITableViewRowAnimationMiddle UITableViewRowAnimationAutomatic 读者如果感兴趣的话,可以自己试着体会一下这几种动画的效果。 QQ学习群:

56 ·添加单元格记录 我们知道表视图中的编辑模式类型有三种: 1. UITableViewCellEditingStyleNone 2
·添加单元格记录 我们知道表视图中的编辑模式类型有三种: 1. UITableViewCellEditingStyleNone 2. UITableViewCellEditingStyleDelete 3. UITableViewCellEditingStyleInsert 然后我们在实现添加单元格信息的功能之前,要先定义几个插入类型的编辑模式, 这要在实现相应功能之前做一个判断,将第一行单元格的编辑模式设置为插入。 42.- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView 43. editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { 44. if(indexPath.row == 0){ 45. return UITableViewCellEditingStyleInsert; 46. }else{ 47. return UITableViewCellEditingStyleDelete; 48. } 49.} QQ学习群:

57 这样我们就把表视图中第一个单元格的编辑模式设置成了插入模式,接下来就通过commitEditingSyle代理方法实现单元格的插入。我们在当前单元格下方插入新的单元格,所以我们先要定义一个静态变量,用于定位单元格的位置。 50.static int count = 1; 51.- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 52.{ if(editingStyle == UITableViewCellEditingStyleDelete){ [listofFile removeObjectAtIndex:indexPath.row]; [_tableView withRowAnimation:UITableViewRowAnimationFade];} else if(editingStyle == UITableViewCellEditingStyleInsert){ NSString *CountryName = [NSString %d",count]; [listofFile insertObject:CountryName atIndex:indexPath.row+1]; NSIndexPath *_indexPath = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:0]; [_tableView withRowAnimation:UITableViewRowAnimationMiddle]; count++; } 65.} QQ学习群:

58 我们在这里初始化了新插入单元格的内容,通过stringWithFormat方法实现了字符串的初始化,插入完成之后,要将count的值加1,让插入的位置下移一行。
QQ学习群:

59 单击添加按钮之后,在当前单元格下一行添加一个行新记录,如图6-20所示。这些添加删除效果都已封装好,我们用户只需要通过相应的代理方法去实现即可。
在实现了添加和删除功能之后,我们一起来了解一下这两个功能实现的原理。 首先,当我们进入编辑模式后,UITableView会向其DataSource发送tableView:canEditRowAtindexPath:消息询问每个indexPath是否都可以编辑,如果单元格不可编辑,则返回NO;同样的,对可以编辑的单元格则返回YES; 然后,UITableView会向其代理delegate发送tableView:editingStyleForRowAtindexPath:消息,来询问编辑的模式是插入还是删除。它的默认值是删除,即UITableViewCellEditingStyleDelete。 当点击”Delete”按钮或者”加号”按钮时,UITableView向其DataSource发送tableView:commitEditingStyle:forRowAtIndexPath:消息,根据传递editingStyle来执行实际的删除或插入操作,其流程是先修改tableView的数据模型,向其中删除或插入对应数据项,然后再调整tableView的显示,删除或插入对应的单元格。 QQ学习群:

60 ·重新排列单元格记录 要实现单元格移动的功能,首先还是要实现一个BOOL类型的代理方法,返回YES值让单元格能够移动。 66.- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { return YES; 68.} 实现移动单元格的步骤也有2步: 1.通过数组移除需要移动单元格在表视图中的记录; 2.通过数组在需要移动到的位置上添加对应的数据。 若不按照这两个步骤来实现移动单元格效果,会造成虽然表示中显示的已经移动,但是实际上在数组中的数据还是按原来的顺序进行排列,等于没有达到移动单元格内容的效果。我们下面来看一下实现方法的代码。 QQ学习群:

61 69. - (void)tableView:(UITableView
69.- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *) 70.sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath 71.{ NSUInteger removeRow = [sourceIndexPath row]; NSUInteger insertRow = [destinationIndexPath row]; id object = [listofFile objectAtIndex:removeRow]; [listofFile removeObjectAtIndex:removeRow]; [listofFile insertObject:object atIndex:insertRow]; 77.} 这里我们定义了两个整型数据,分别代表需要移动的原单元格和要移动到特定位置的目的单元格。然后通过上述两个步骤来进行单元格的移动。 QQ学习群:

62 至此,我们基本上完成了对表视图编辑模式基础内容的学习。有些读者可能会发现在导航栏右侧的编辑按钮和通常iPhone上的按钮有所不一样,当我们点击Edit按钮之后,在编辑模式下,按钮按常理应该会变成“Done”,这里并没有变化。那么,我们其实可以自定义一个editButton来完善这个不足。 QQ学习群:

63 我们就不用系统自带的editButtonItem。我们定义一个载入自定义编辑按钮的方法。
78.- (void)loadButton 79.{ 80.editButton = [[UIBarButtonItem alloc] 81.style:UIBarButtonItemStyleBordered target:self self.navigationItem.rightBarButtonItem = editButton; [editButton release]; 85.} 我们初始化了一个按钮,并将它命名为“编辑”,这样我们在程序中就能使用中文的按钮。然后实现编辑按钮的单击事件。 QQ学习群:

64 86.- (void)editAction 87.{ if(editButton.title { [editButton [editButton setStyle:UIBarButtonItemStyleDone]; [_tableView setEditing:YES animated:YES]; }else{ [editButton [editButton setStyle:UIBarButtonItemStylePlain]; [_tableView setEditing:NO animated:YES]; } 98.} QQ学习群:

65 这里对编辑的按钮做了一个简单的判断,如果当前是在编辑模式,那么按钮的标题就为“确定”,反之文本就是“编辑”。最后我们将这个自定义编辑按钮的方法在viewDidLoad方法中调用。最后构建并运行程序,看到最后的效果如图所示。 QQ学习群:

66 本章小结 本章讲解了UIImageView以及UITableView的基本使用方法,在IOS开发中,这两个视图是使用频率较多的视图,许多模型都是建立它们之上,在进行自定义以实现自己项目的需求。所以希望读者能够掌握UIImageView和UITableView的使用。 QQ学习群:

67 课后习题 1.将第五章习题的第一小题中的UIView修改成UIImageView,并比较二者在实现上的相同点和不同点。 2.通过UITableView实现全国省份的显示。 3.在第二题的基础上,增加“东北”、“西北”、“华中”、“华东”和“华南”地区的分类,通过group类型的UITableView实现,设置header头。 4.为每个UITableViewCell添加一个自定义按钮。 QQ学习群:


Download ppt "Http://www.xs360.cn 《IOS应用开发教程》 QQ学习群:262779381."

Similar presentations


Ads by Google