从零开始学ios开发(十二):Table Views(中)UITableViewCell定制
我们继续学习Table View的内容,这次主要是针对UITableViewCell,在前一篇的例子中我们已经使用过UITableViewCell,一个默认的UITableViewCell包含imageView、textLabel、detailTextLabel等属性,但是很多时候这些默认的属性并不能满足需要,其实更多的时候我们想自己制定UITableViewCell的内容,这篇学习的就是制定自己的UITableViewCell。
UITableViewCell继承自UIView,因此它可以加载任意的subView在上面,基于这一点,我们就可以定制自己的UITableViewCell了。制定UITableViewCell有2种方法,一种是写代码生成UITableViewCell控件上的内容,另一种是拖控件到一个UITableViewCell控件上,这两种方法都会用一个例子来进行说明。
首先我们使用code的方法,来定制自己的UITableViewCell
1)创建一个新的项目,template选择Single View Application,命名为Cells
2)添加Table View,连接delegate和data source到File's Owner 选中BIDController.xib文件,从Object Library中拖一个Table View到view上,然后选中view中的table view,打开Connections Inspector,拖动dataSource和delegate右边的小圆圈到File's Owner上
3)添加Cell 在Project navigator中选中Cells文件夹,然后command+N,添加一个新的文件。在弹出的对话框中,左边选择Cocoa Touch,右边选择Objective-C,然后点击Next
在下一个对话框中把Class命名为BIDNameAndColorCell,Subclass of选择UITableViewCell,然后点击Next
在下一个对话框中选择Create,完成创建
BIDNameAndColor文件继承自UITableViewCell,我们将先对其进行定制,添加一些我们需要的控件,当BIDViewController中调用table cell的时候,就直接调用这个文件即可。
4)添加BIDNameAndColorCell代码 打开BIDNameAndColorCell.h文件,添加如下代码

- #import <UIKit/UIKit.h>
- @interface BIDNameAndColorCell : UITableViewCell
- @property (copy, nonatomic) NSString *name;
- @property (copy, nonatomic) NSString *color;
- @end

我们将在table view cell中显示2个字符串,一个是name,另一个是color,显示的内容会从之后定义的NSArray中读取。(注意,我们这里使用的是copy,而不是通常使用的strong,使用copy的好处是不会改变原有的字符串中的内容,当然在这里我们也不会改变字符串的内容,你如果使用了strong也问题不大,不过书上的建议是如果一个property是NSString,最好使用copy)
接着编辑BIDNameAndColorCell.m文件,添加下面的code

- #import "BIDNameAndColorCell.h"
- #define kNameValueTag 1
- #define kColorValueTag 2
- @implementation BIDNameAndColorCell
- @synthesize name;
- @synthesize color;

首先添加2个常量kNameValueTag和kColorValueTag,这2个常量用来标识table view cell中的name和color。接着就是name和color的synthesize了,和之前例子中的一样。
下面修改BIDNameAndColorCell.m中已存在的initWithStyle:reuseIdentifier:方法

- - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
- {
- self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
- if (self) {
- // Initialization code
- CGRect nameLabelRect = CGRectMake(0, 5, 70, 15);
- UILabel *nameLabel = [[UILabel alloc] initWithFrame:nameLabelRect];
- nameLabel.textAlignment = UITextAlignmentRight;
- nameLabel.text = @"Name:";
- nameLabel.font = [UIFont boldSystemFontOfSize:12];
- [self.contentView addSubview:nameLabel];
- CGRect colorLabelRect = CGRectMake(0, 26, 70, 15);
- UILabel *colorLabel = [[UILabel alloc] initWithFrame:colorLabelRect];
- colorLabel.textAlignment = UITextAlignmentRight;
- colorLabel.text = @"Color:";
- colorLabel.font = [UIFont boldSystemFontOfSize:12];
- [self.contentView addSubview:colorLabel];
- CGRect nameValueRect = CGRectMake(80, 5, 200, 15);
- UILabel *nameValue = [[UILabel alloc]initWithFrame:nameValueRect];
- nameValue.tag = kNameValueTag;
- [self.contentView addSubview:nameValue];
- CGRect colorValueRect = CGRectMake(80, 25, 200, 15);
- UILabel *colorValue = [[UILabel alloc]initWithFrame:colorValueRect];
- colorValue.tag = kColorValueTag;
- [self.contentView addSubview:colorValue];
- }
- return self;
- }

上面的代码应该还是比较容易理解的吧,创建了4个UILabel,设置完UILabel的属性后,把他们加入到UITableViewCell中,table view cell有一个默认的view叫做contentView,contenView负责容纳其他的subView,因此上面code中所创建的4个UILabel都会添加到contentView中,使用的语句是[self.contentView addSubview:colorValue]
再说一下上面创建的4个UILabel在这个例子中的作用,nameLabel和colorLabel的作用是纯粹的Label,它们的值不会在改变,在这只它们属性的使用已经分别为它们赋值了。nameValue和colorValue这2个label是用来显示NSArray中的值的,这也是为什么只有这2个label会有property,因为它们需要改变值。另外在code中还未这2个label制定了tag,这个tag的具体作用是通过它来标识具体的label,添加下面的code,就会有所了解。

- - (void)setName:(NSString *)n {
- if(![n isEqualToString:name]) {
- name = [n copy];
- UILabel *nameLabel = (UILabel *)[self.contentView viewWithTag:kNameValueTag];
- nameLabel.text = name;
- }
- }
- - (void)setColor:(NSString *)c {
- if(![c isEqualToString:color]) {
- color = [c copy];
- UILabel *colorLabel = (UILabel *)[self.contentView viewWithTag:kColorValueTag];
- colorLabel.text = color;
- }
- }

@synthesize会帮我们自动创建get和set方法,但在这里我们需要自己写set方法,因此通过上面的code来覆盖系统自动为我们生成的set方法。2个set方法的实现是一样的。首先比较新赋值的字符串和旧的字符串是否一样,如果不一样就进行赋值。然后需要解释的就是这句话 UILabel *colorLabel = (UILabel *)[self.contentView viewWithTag:kColorValueTag]; 如果找到table view cell中的控件?即使使用刚才我们创建的2个常量,因为每一个控件的tag值都是不一样的,因此根据tag值就可以很方便的找到我们需要的控件,viewWithTag返回的类型是(UIView *),所以我们将类型强制转换成(UILable *),就可以得到我们需要的Label了,然后对Label进行赋值。
5)添加BIDViewController代码 打开BIDViewController.h,添加如下代码

- #import <UIKit/UIKit.h>
- @interface BIDViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
- @property (strong, nonatomic) NSArray *computers;
- @end

很简单,不解释。
打开BIDViewController.m,添加如下代码

- #import "BIDViewController.h"
- #import "BIDNameAndColorCell.h"
- @implementation BIDViewController
- @synthesize computers;
- ......
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view, typically from a nib.
- NSDictionary *row1 = [[NSDictionary alloc] initWithObjectsAndKeys:
- @"MacBook", @"Name", @"White", @"Color", nil];
- NSDictionary *row2 = [[NSDictionary alloc] initWithObjectsAndKeys:
- @"MacBook Pro", @"Name", @"Silver", @"Color", nil];
- NSDictionary *row3 = [[NSDictionary alloc] initWithObjectsAndKeys:
- @"iMac", @"Name", @"Silver", @"Color", nil];
- NSDictionary *row4 = [[NSDictionary alloc] initWithObjectsAndKeys:
- @"Mac Mini", @"Name", @"Silver", @"Color", nil];
- NSDictionary *row5 = [[NSDictionary alloc] initWithObjectsAndKeys:
- @"Mac Pro", @"Name", @"Silver", @"Color", nil];
- self.computers = [[NSArray alloc] initWithObjects:row1, row2, row3, row4, row5, nil];
- }
- - (void)viewDidUnload
- {
- [super viewDidUnload];
- // Release any retained subviews of the main view.
- // e.g. self.myOutlet = nil;
- self.computers = nil;
- }

首先我们引入BIDNameAndColor的头文件,之后我们将会创建它的实例,在viewDidLoad中,创建了5个NSDictionary,用于保存name和color名值对,使用的方法是initWithObjectsAndKeys,就是说下面的内容前一个作为object,后一个作为key,举个例子,最后一个NSDictionary中,@"Mac Pro"就是object,@"Name"就是key。最后将5个NSDictionary保存到NSArray中(computers中)
在添加下面的code

- #pragma mark -
- #pragma mark Table Data Source Methods
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return [self.computers count];
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- static NSString *CellTableIdentifier = @"CellTableIdentifier";
- BIDNameAndColorCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];
- if(cell == nil) {
- cell = [[BIDNameAndColorCell alloc]
- initWithStyle:UITableViewCellStyleDefault
- reuseIdentifier:CellTableIdentifier];
- }
- NSUInteger row = [indexPath row];
- NSDictionary *rowData = [self.computers objectAtIndex:row];
- cell.name = [rowData objectForKey:@"Name"];
- cell.color = [rowData objectForKey:@"Color"];
- return cell;
- }

tableView:numberOfRowsInSection: 返回section中的行数 tableView:cellForRowAtIndexPath: 这个方法稍微有些不同,它吃创建了一个BIDNameAndColorCell的对象,而不是创建默认的UITableViewCell,这样就可以直接使用我们自己定义的cell了,这里虽然也指定了UITableViewCellStyleDefault,但是不会起作用,因为我们自己定义了cell
之后的代码应该很好理解,很直观。
6)编译运行
7)使用UITableViewCell控件,创建项目,添加table view,连接File's Owner 现在我们使用第二种方法来定制UITableViewCell,最终的效果和上面的例子一样,创建一个新的项目,同样选择Single View Application,命名为Cells2
添加Table View,连接delegate和data source到File's Owner
8)添加BIDNameAndColorCell文件并编辑 和上面的例子一样,添加BIDNameAndColorCell文件
打开BIDNameAndColorCell.h文件,添加如下代码

- #import <UIKit/UIKit.h>
- @interface BIDNameAndColorCell : UITableViewCell <UITableViewDelegate, UITableViewDataSource>
- @property (copy, nonatomic) NSString *name;
- @property (copy, nonatomic) NSString *color;
- @property (strong, nonatomic) IBOutlet UILabel *nameLabel;
- @property (strong, nonatomic) IBOutlet UILabel *colorLabel;
- @end

和之前有所不同的是,我们多添加了2个Outlet,因为之后要添加xib,因此这2个outlet会指向xib上了2个UILabel
打开BIDNameAndColorCell.m文件,添加如下代码

- #import "BIDNameAndColorCell.h"
- @implementation BIDNameAndColorCell
- @synthesize name;
- @synthesize color;
- @synthesize nameLabel;
- @synthesize colorLabel;
- - (void)setName:(NSString *)n {
- if(![n isEqualToString:name]) {
- name = [n copy];
- nameLabel.text = name;
- }
- }
- - (void)setColor:(NSString *)c {
- if(![c isEqualToString:color]) {
- color = [c copy];
- colorLabel.text = color;
- }
- }

我们重新定义了setName和setColor,这里不需要使用tag,因为我们直接使用outlet就可以找到我们需要的UILabel,另外我们也没在initWithStyle:reuseIdentifier中创建4个Label,因为我们会在之后UITableViewCell控件中添加。
9)添加xib 在Project navigator中鼠标右键单击Cells2文件夹,然后选择New File...,在填出的对话框中左边选择User Interface,右边选择Empty,点击Next
之后的Device Family中选择iphone,点击Next
命名为BIDNameAndColorCell.xib,点击Create
在Project navigator中选中BIDNameAndColorCell.xib文件,因为我们创建的是Empy,因此GUI中什么都没有,在Object library中找到Table View Cell 拖到GUI中
选中view中的table view cell,打开Attributes inspector,找到Identifier,并设置为CellTableIdentifier 这个Identifier就是之前我们code中用到过的Identifier
10)向table view cell中添加控件 往table view cell中拖4个UILable
将左上方的UILabel命名为"Name:",然后设置为粗体(在attribute inspector中设置) 将左下方的UILabel命名为"Color:",然后设置为粗体(在attribute inspector中设置) 将右上方的UILabel拉到右边出现辅助线的位置 将右下方的UILabel拉到右边出现辅助线的位置 设置完成后的样子如下
(不必将右边2个Label的文字去掉,程序运行是会为它们重新赋值)
11)关联 接着我们将BIDNameAndColorCell.xib和BIDNameAndColorCell文件关联起来,选中GUI中的view,打开Identify inspector,将Class指定为BIDNameAndColorCell
还是选中view,切换到connections inspector,里面有colorLabel和nameLabel 将colorLabel和nameLabel拖到view中对应的UILabel上,关联起来(最右边的2个label)
12)写代码 打开BIDViewController.h文件,添加如下代码

- #import <UIKit/UIKit.h>
- @interface BIDViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
- @property (strong, nonatomic) NSArray *computers;
- @end

这个和上一个例子一样,不解释了,打开BIDViewController.m文件,添加如下代码

- #import "BIDViewController.h"
- #import "BIDNameAndColorCell.h"
- @implementation BIDViewController
- @synthesize computers;
- ......
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view, typically from a nib.
- NSDictionary *row1 = [[NSDictionary alloc] initWithObjectsAndKeys:
- @"MacBook Air", @"Name", @"Silver", @"Color", nil];
- NSDictionary *row2 = [[NSDictionary alloc] initWithObjectsAndKeys:
- @"MacBook Pro", @"Name", @"Silver", @"Color", nil];
- NSDictionary *row3 = [[NSDictionary alloc] initWithObjectsAndKeys:
- @"iMac", @"Name", @"Silver", @"Color", nil];
- NSDictionary *row4 = [[NSDictionary alloc] initWithObjectsAndKeys:
- @"Mac Mini", @"Name", @"Silver", @"Color", nil];
- NSDictionary *row5 = [[NSDictionary alloc] initWithObjectsAndKeys:
- @"Mac Pro", @"Name", @"Silver", @"Color", nil];
- self.computers = [[NSArray alloc] initWithObjects:row1, row2,
- row3, row4, row5, nil];
- }
- - (void)viewDidUnload
- {
- [super viewDidUnload];
- // Release any retained subviews of the main view.
- // e.g. self.myOutlet = nil;
- self.computers = nil;
- }
- #pragma mark -
- #pragma mark Table View Data Source Methods
- - (NSInteger)tableView:(UITableView *)tableView
- numberOfRowsInSection:(NSInteger)section {
- return [self.computers count];
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- static NSString *CellTableIdentifier = @"CellTableIdentifier";
- static BOOL nibsRegistered = NO;
- if(!nibsRegistered) {
- UINib *nib = [UINib nibWithNibName:@"BIDNameAndColorCell" bundle:nil];
- [tableView registerNib:nib forCellReuseIdentifier:CellTableIdentifier];
- nibsRegistered = YES;
- }
- BIDNameAndColorCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];
- NSUInteger row = [indexPath row];
- NSDictionary *rowData = [self.computers objectAtIndex:row];
- cell.name = [rowData objectForKey:@"Name"];
- cell.color = [rowData objectForKey:@"Color"];
- return cell;
- }

我们所要关心的就是tableView:cellForRowAtIndexPath这个方法中的if语句这段代码:
if(!nibsRegistered) { UINib *nib = [UINib nibWithNibName:@"BIDNameAndColorCell" bundle:nil]; [tableView registerNib:nib forCellReuseIdentifier:CellTableIdentifier]; nibsRegistered = YES; }
UINib通过xib文件的名字找到xib文件,然后tableView会调用这个xib文件,nibsRegistered保证只有第一次调用这个方法的时候会去寻找并载入xib,之后则不会。
13)编译运行 编译运行程序,得到的结果和之前的一个程序应该是一样的
14)总结 这篇文章使用2种方式定制了UITableViewCell,一种是代码实现,另一种是传统的拖控件实现,2种方法应该说各有利弊,不一定拖控件就是好的,我应该已经预感到以后的界面布局应该都使用写代码来实现,已经有好几个博友通过我的例子学习但是得到的界面上面控件的布局出现了差错,目前的原因是他们使用的模拟器和我的不一样,我使用的是iPhone 5.0 Simulator,他们可以是用其他的模拟器,但是我觉得照成差错的原因是因为学习到现在我们都是使用拖控件的方法来布局的,这个会造成差错,如果都是用code来实现布局,那么情况应该会变得一致。
下一篇的内容会讲到Table View的Section、index、搜索栏等等,内容比较多也比较实用,实现的效果如下 我会尽快写完放上来的,谢谢大家的关注,有任何问题大家留言吧,如果我知道的话,我会尽量回答,谢谢!
从零开始学ios开发(十二):Table Views(中)UITableViewCell定制的更多相关文章
- 从零开始学ios开发(二十):Application Settings and User Defaults(下)
在上一篇的学习中,我们知道了如何为一个App添加它的Settings设置项,在Settings设置项中我们可以添加哪些类型的控件,这些控件都是通过一个plist来进行管理的,我们只需对plist进行修 ...
- 从零开始学ios开发(二):Hello World!来啦!
今天看了书的第二章,主要介绍了一下Xcode的使用方法和一些必要的说明,最后做了一个“Hello World!”的小程序,其实就是在屏幕上用一个Label显示“Hello World!”,一行代码都没 ...
- 从零开始学ios开发(二):Hello World!
今天看了书的第二章,主要介绍了一下Xcode的使用方法和一些必要的说明,最后做了一个“Hello World!”的小程序,其实就是在屏幕上用一个Label显示“Hello World!”,一行代码都没 ...
- 从零开始学ios开发(十二):Table Views(上)
这次学习的控件非常重要且非常强大,是ios应用中使用率非常高的一个控件,可以说几乎每个app都会使用到它,它就是功能异常强大的Table Views.可以打开你的iphone中的phone.Messa ...
- 从零开始学 iOS 开发的15条建议
事情困难是事实,再困难的事还是要每天努力去做是更大的事实. 因为我是一路自学过来的,并且公认没什么天赋的前提下,进步得不算太慢,所以有很多打算从零开始的朋友会问我,该怎么学iOS开发.跟粉丝群的朋友交 ...
- 从零开始学ios开发(十六):Navigation Controllers and Table Views(下)
终于进行到下了,这是关于Navigation Controllers和Table Views的最后一个例子,稍微复杂了一点,但也仅仅是复杂而已,难度不大,我们开始吧. 如果没有上一篇的代码,可以从这里 ...
- 从零开始学ios开发(十五):Navigation Controllers and Table Views(中)
这篇内容我们继续上一篇的例子接着做下去,为其再添加3个table view的例子,有了之前的基础,学习下面的例子会变得很简单,很多东西都是举一反三,稍稍有些不同的内容,好了,闲话少说,开始这次的学习. ...
- 从零开始学ios开发(十四):Navigation Controllers and Table Views(上)
这一篇我们将学习一个新的控件Navigation Controller,很多时候Navigation Controller是和Table View紧密结合在一起的,因此在学习Navigation Co ...
- 从零开始学ios开发(十三):Table Views(下)Grouped and Indexed Sections
在前面2篇关于Table View的介绍中,我们使用的Style都是Plain,没有分组,没有index,这次学习的Table View和iphone中的通讯录很像,有一个个以字符为分割的组,最右边有 ...
- 从零开始学ios开发(十九):Application Settings and User Defaults(上)
在iphone和ipad中,有一个东西大家一定很熟悉,那个东西就是Settings. 这次要学习的东西说白了很简单,就是学习如何在Settings中对一个app的某些属性进行设置,反过来,在app中更 ...
随机推荐
- 浅议tomcat与classloader
关于tomcat和classloader的文章,网上多如牛毛,且互相转载,所以大多数搜到的基本上是讲到了tomcat中classloader的几个层次,对于初接触classloader,看了之后还是只 ...
- BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会 树形DP
[Usaco2010 Mar]gather 奶牛大集会 Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会.每个奶牛居住在 N(1 ...
- GSS6 4487. Can you answer these queries VI splay
GSS6 Can you answer these queries VI 给出一个数列,有以下四种操作: I x y: 在位置x插入y.D x : 删除位置x上的元素.R x y: 把位置x用y取替 ...
- CSS制作彩虹效果
今天看到一篇文章,说到margin的塌陷的问题,并提供了好几个例子. 自己之前还没怎么遇到过这个问题,正好来研究一下. <div class="box1"></d ...
- java随笔 乱腾腾的 一些东西
调用requonse.getWriter()方法时可实现文本字符串数据输出,调用response.getOutputStream()方法可现实字节流数据的输出.两种输出方式threadlocal模式和 ...
- Spring里用@RequestParam接受Date类型的url参数
首先引入joda-time包.maven的dependency: <dependency> <groupId>joda-time</groupId> <art ...
- iOS Foundation框架 -2.常用集合类简单总结
Foundation框架中常用的类有:NSString.NSArray.NSSet.NSDictionary 以及它们对应的子类 NSMutableString.NSMutableArray.NSMu ...
- 这是html5中WebGL的演示
这是html5中WebGL的演示,让我们与他人分享爱您发送短消息.每次你进入它使用不同的位置,新的爱情点被添加到全球.让世界更明亮的地方与你的朋友分享! 源文件:部分代码:<!DOCTYPE h ...
- yaf运行错误:Class 'Yaf_Application' not found
提示:致命错误 Yaf_Application 基类没有加载进去 一检查:phpinfo() 里yaf 扩展有没有安装上 扩展也安装进去了 这时在分布式配置文件的重写 也是正确 这时百思不得其解,没办 ...
- 使用ANT 生成Xfire 客户端端文件
这里需要用到的JAR包 : XmlSchema-1.1.jar activation-1.1.jar commons-codec-1.3.jar commons-httpclient-3.0.jar ...