从零开始学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中更 ...
随机推荐
- (转)Linux IO模式及 select、poll、epoll详解
本文为转载,并作了部门调整.修改. [原文出处:https://segmentfault.com/a/1190000003063859] 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么 ...
- Lnmp下安装memcached
Lnmp下安装memcached 1.先安装 libevent,再安装 Memcached主程序 # tar xf libevent-2.0.21-stable.tar.gz # cd ...
- VB.NET 小程序 3
Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ...
- .NET DLL 保护措施详解(三)最终效果
针对.NET DLL 保护措施详解所述思路完成最终的实现,以下为程序包下载地址 下载 注意: 运行环境为.net4.0,需要安装VS2015 C++可发行组件包vc_redist.x86.exe.然后 ...
- Part 12 Angularjs filter by multiple properties
In the example below, we are using multiple search textboxes. As you type in the "Search name&q ...
- Mac下利用eclipse打包cocos2dx安卓apk
上一篇博客中我们已经配置好了JDK和ANT,接下来我们就可以使用eclipse将我们开发好的cocos2dx项目进行打包了. 首先,我们需要准备好下面的内容 配置环境变量,打开"终端&quo ...
- 【学习笔记】【C语言】关键字
1.关键字就是C语言提供的有特殊含义的符号,也叫做“保留字” *C语言一共提供了32个关键字,这些关键字都被C语言赋予了特殊含义 auto double int struct break else l ...
- (转)Yale CAS + .net Client 实现 SSO(6)
第一部分:安装配置 Tomcat 第二部分:安装配置 CAS 第三部分:实现 ASP.NET WebForm Client 第四部分:实现基于数据库的身份验证 第五部分:扩展基于数据库的身份验证 第六 ...
- struts2中访问servlet API
Struts2中的Action没有与任何Servlet API耦合,,但对于WEB应用的控制器而言,不访问Servlet API几乎是不可能的,例如需要跟踪HTTP Session状态等.Struts ...
- <Linux系统hostname命令详解>
hostname命令的用法的小知识我们都知道hostname命令是查看主机名和修改主机名的. [root@apache ~]# hostname //查看本机的主机名apache.example.c ...