从零开始学ios开发(十二):Table Views(中)UITableViewCell定制

咱们继续学习Table View的内容,此次主要是针对UITableViewCell,在前一篇的例子中咱们已经使用过UITableViewCell,一个默认的UITableViewCell包含imageView、textLabel、detailTextLabel等属性,可是不少时候这些默认的属性并不能知足须要,其实更多的时候咱们想本身制定UITableViewCell的内容,这篇学习的就是制定本身的UITableViewCell。iphone

UITableViewCell继承自UIView,所以它能够加载任意的subView在上面,基于这一点,咱们就能够定制本身的UITableViewCell了。制定UITableViewCell有2种方法,一种是写代码生成UITableViewCell控件上的内容,另外一种是拖控件到一个UITableViewCell控件上,这两种方法都会用一个例子来进行说明。布局

首先咱们使用code的方法,来定制本身的UITableViewCell学习

1)建立一个新的项目,template选择Single View Application,命名为Cells this

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上 atom

3)添加Cell 在Project navigator中选中Cells文件夹,而后command+N,添加一个新的文件。在弹出的对话框中,左边选择Cocoa Touch,右边选择Objective-C,而后点击Next spa

在下一个对话框中把Class命名为BIDNameAndColorCell,Subclass of选择UITableViewCell,而后点击Next 3d

在下一个对话框中选择Create,完成建立 code

BIDNameAndColor文件继承自UITableViewCell,咱们将先对其进行定制,添加一些咱们须要的控件,当BIDViewController中调用table cell的时候,就直接调用这个文件便可。对象

4)添加BIDNameAndColorCell代码 打开BIDNameAndColorCell.h文件,添加以下代码blog

复制代码
#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

相关文章
相关标签/搜索