从零开始学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)编译运行

Cells

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、搜索栏等等,内容比较多也比较实用,实现的效果如下 我会尽快写完放上来的,谢谢大家的关注,有任何问题大家留言吧,如果我知道的话,我会尽量回答,谢谢!

Cells2

从零开始学ios开发(十二):Table Views(中)UITableViewCell定制,布布扣,bubuko.com

时间: 07-01

从零开始学ios开发(十二):Table Views(中)UITableViewCell定制的相关文章

从零开始学ios开发(二):Hello World!

今天看了书的第二章,主要介绍了一下Xcode的使用方法和一些必要的说明,最后做了一个“Hello World!”的小程序,其实就是在屏幕上用一个Label显示“Hello World!”,一行代码都没有写,拖拖控件,改变一下Label字体大小颜色什么的,还是比较简单的,下面把这个过程写一下,至于xcode的使用说明就不在这里具体叙述了,反正到时候用到哪就介绍到哪里吧. 1)启动Xcode 选择“Create a new Xcode project”,创建一个新的项目. 2)模板选择,选择“Sin

从零开始学ios开发(十二):Table Views(上)

这次学习的控件非常重要且非常强大,是ios应用中使用率非常高的一个控件,可以说几乎每个app都会使用到它,它就是功能异常强大的Table Views.可以打开你的iphone中的phone.Messages.Contacts.Mail.Settings等等等等,这些都用到了Table Views. 在Table Views中,Table是用来显示一系列数据的,每条数据占用且只占用一行(一个table cell),在ios中没有规定table到底可以容纳多少行数据,也就是说,只要内存足够多,tab

从零开始学ios开发(十五):Navigation Controllers and Table Views(中)

这篇内容我们继续上一篇的例子接着做下去,为其再添加3个table view的例子,有了之前的基础,学习下面的例子会变得很简单,很多东西都是举一反三,稍稍有些不同的内容,好了,闲话少说,开始这次的学习. 如果没有上一篇的代码,可以从这里下载Nav_1 1)第三个subtableview:Controls on Table Rows这个例子,我们将为每个table view的每一行添加一个按钮,这个按钮将放在accessory icon的位置(之前我们使用过accessoryType,其实这也是一个

从零开始学ios开发(十四):Navigation Controllers and Table Views(上)

这一篇我们将学习一个新的控件Navigation Controller,很多时候Navigation Controller是和Table View紧密结合在一起的,因此在学习Navigation Controller的同时,我们还将继续学习Table View其他一些特性,毕竟Navigation Controller还是相对来说毕竟简单的,没有什么太大的花头,它的主要作用就是一个view的切换,切来切去,而Table View的花头就比较多了,这次我们将这2个控件结合在一起进行学习. 再多说一

从零开始学ios开发(十三):Table Views(下)Grouped and Indexed Sections

在前面2篇关于Table View的介绍中,我们使用的Style都是Plain,没有分组,没有index,这次学习的Table View和iphone中的通讯录很像,有一个个以字符为分割的组,最右边有一列小字符作为index,最顶端有一个搜索栏可以进行搜索,好了,下面开始这次的学习. 1)创建一个新的项目,template选择Single View Application,命名为Sections 2)添加Table View,连接delegate和data source到File's Owner

从零开始学ios开发(十九):Application Settings and User Defaults(上)

在iphone和ipad中,有一个东西大家一定很熟悉,那个东西就是Settings. 这次要学习的东西说白了很简单,就是学习如何在Settings中对一个app的某些属性进行设置,反过来,在app中更改了一些属性值,也会反应到Settings中,这个功能很常用,实现起来也相对简单,但是内容还是比较多的. 首先还是对Settings进行一个简单的说明,虽然我们经常打开Settings,但是很少对Settings进行过仔细的研究,不过作为一名ios的开发人员,有这个必要对Settings进行一番探索

从零开始学ios开发(十八):Storyboards(下)

这篇我们完成Storyboards的最后一个例子,之前的例子中没有view之间的切换,这篇加上这个功能,使Storyboards的功能完整呈现.在Storyboards中负责view切换的东西叫做“segue”,只需对它进行简单的设置即可,一切都是傻瓜式的,无需繁琐的代码.好了,开始我们的例子吧. 1)Create a Simple Storyboard创建一个project,左边选择Application,右边选择Empty Application template(我们这里不使用Single

从零开始学ios开发(十):Multiview Applications(多个xib之前的切换)

这篇学习的主要内容是Multiview,在我们学习iphone旋转的时候,介绍过多个view的使用方法,不过这里的view和旋转屏幕中所指的多个view是不同的,旋转屏幕中涉及到的多个view是在一个xib文件中的,而我们这里所指的mulitview,则是指多个xib,在多个xib中进行view的切换,也就是从一个xib切换到另一个xib,而每个xib中只有一个view. 另外的一个不同点体现在创建项目的时候,到目前为止,我们创建的所有项目的template都是single view,这次创建的

从零开始学ios开发(九):Swapping Views

这篇的内容是切换Views,也是上一篇中提到的第三种当iphone发生旋转后改变布局的方式,先回顾一下上一篇中提到的三种方式 1.使用Autosizing 2.写code 3.重新弄个View,替换原先的View 切换View,顾名思义就是在两个不同的View中间进行切换,那么我们至少需要有2个View,一个View展现当竖着(Portrait)拿iphone时的界面,另一个View展现当横着(Landscape)拿iphone是的界面,当我们旋转iphone时,就在这2个View之间进行切换,