您的位置:首页 > 其它

自定义Cell的三种方式

2016-02-23 00:00 239 查看
摘要: 文中介绍了三种创建自定义cell的方式,重点需要关注:
1. 在哪里设置cell的外观,组件...
2. 如何注册cell

在TableView中添加自定义Cell有三种方式:

纯代码实现Cell,不依赖xib或storyboard文件

Storyboard + 代码的方式

xib文件 + 代码的方式

##方式1: 纯代码实现Cell

###Step 1创建MyCell类

//MyCell.h
#import <UIKit/UIKit.h>

@interface MyCell : UITableViewCell
- (void)setTheValue:(NSString *)str;
@end

#import "MyCell.h"

@interface MyCell ()
@property (nonatomic, strong)UILabel *label;
@end

//MyCell.m
@implementation MyCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//创建内容组件
_label = [[UILabel alloc] initWithFrame:CGRectMake(100, 0, 50, 50)];
[self.contentView addSubview:_label];
}
return self;
}

- (void)setTheValue:(NSString *)str {
NSString *text = _label.text;
if(![str isEqualToString:text]) {
_label.text = str;
}
}
@end

Cell内部的内容组件都在initWithStyle: reuseIdentifier:方法中创建。

###Step 2添加TableView
在storyboard中添加一个TableView,并把其中的Cell删除。

###Step 3实现ViewController

//MyViewController.h
#import <UIKit/UIKit.h>
@interface MyViewController : UITableViewController
@end

//MyViewController.m
#import "MyViewController.h"
#import "MyCell.h"
@interface MyViewController ()
@property (nonatomic, copy) NSArray *dataSource;
@end

@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataSource = @[@"1", @"2", @"3"];

//必须在这里注册才能确保重用cell
[self.tableView registerClass:[MyCell class] forCellReuseIdentifier:@"CellIdentifier"];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataSource.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];
[cell setTheValue:[self.dataSource objectAtIndex:indexPath.row]];
return cell;
}
@end

由于storyboard中并没有cell,因此必须在代码中注册自定义的cell,以实现cell重用。

方式2: storyboard + 代码

Step 1创建MyCell类

//MyCell.h
#import <UIKit/UIKit.h>
@interface MyCell : UITableViewCell
- (void)setTheValue:(NSString *)str;
@end

//MyCell.m
#import "MyCell.h"
@interface MyCell ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@end

@implementation MyCell
- (void)setTheValue:(NSString *)str {
if(![_label.text isEqualToString:str]) {
_label.text = str;
}
}
@end

Cell的组件内容均在storyboard中实现,因此无需覆盖UITableViewCell的initWithStyle: reuseIdentifier:方法。

Step 2创建TableView和Cell

在storyboard中创建一个TableView,并设置Cell的Identifier和Cell的关联类(MyCell)。然后把一个UILabel拖入Cell中,作为Cell内容组件。最后把storyboard中的label与MyCell中的label通过ctrl-drag的方式连接起来。

Step 3实现ViewController

//MyViewController.h
#import <UIKit/UIKit.h>
@interface MyViewController : UITableViewController
@end

//MyViewController.m

#import "MyViewController.h"
#import "MyCell.h"
@interface MyViewController ()
@property (nonatomic, copy) NSArray *dataSource;
@end

//MyViewController.m
static NSString *CellIdentifier = @"CellIdentifier";
@implementation MyViewController

- (void)viewDidLoad
{
[super viewDidLoad];
self.dataSource = @[@"1", @"2", @"3"];

//不要在这里注册cell!去storyboard中注册!
//[self.tableView registerClass:[MyCell class] forCellReuseIdentifier:CellIdentifier];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataSource.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSString *str = [self.dataSource objectAtIndex:indexPath.row];
[cell setTheValue:str];
return cell;
}
@end

你只需在storyboard为自定义cell注册一次即可!!

注意,由于我们已经在storyboard中设置了cell的Identifier,因此切勿在代码中再对cell进行注册,因为这会导致Cell无法正常显示!!!

同时,你可能已经注意到,在storyboard中创建cell后,如果没有设置cell的identifier,编译器会给出警告。也就是说,在storyboard中创建cell时,编译器更希望你在storyboard设置cell的identifier,而不是在代码中注册。

方式3 xib + 代码

Step 1创建MyCell类

//MyCell.h
#import <UIKit/UIKit.h>
@interface MyCell : UITableViewCell
- (void)setTheValue:(NSString *)str;
@end

//MyCell.m
#import "MyCell.h"
@interface MyCell ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@end

@implementation MyCell
- (void)setTheValue:(NSString *)str {
if(![_label.text isEqualToString:str]) {
_label.text = str;
}
}
@end

Cell的组件内容均在xib文件中实现,因此无需覆盖UITableViewCell的initWithStyle: reuseIdentifier:方法。

###Step 2创建TableView和Cell
在storyboard中创建一个TabelView,并删除其中的cell。

在项目创建一个名为CellXib的xib文件,用于表示cell。打开xib文件,往其中拖入一个label。

###Step 3创建ViewController

//MyViewController.h
#import <UIKit/UIKit.h>
@interface MyViewController : UITableViewController
@end

//MyViewController.m
#import "MyViewController.h"
#import "MyCell.h"
@interface MyViewController ()
@property (nonatomic, copy) NSArray *dataSource;
@end

static NSString *CellIdentifier = @"CellIdentifier";
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataSource = @[@"1", @"2", @"3"];

//仅需要在代码中注册一次
UINib *nib = [UINib nibWithNibName:@"CellXib" bundle:nil];
[self.tableView registerNib:nib forCellReuseIdentifier:CellIdentifier];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataSource.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSString *str = [self.dataSource objectAtIndex:indexPath.row];
[cell setTheValue:str];
return cell;
}
@end

与方式2不同的是,使用xib后,你只需用代码注册cell即可。

##总结
纯代码实现Cell

优点: 我们可以复用这个cell。

缺点: 在编写代码时,无法直观的看到cell的样子。

只需要在代码中注册cell。

不推荐使用

storyboard + 代码

优点: 可以直观的看到cell嵌入到TabelView的效果,同时也方便对cell进行管理。

缺点: 无法复用这个cell。因为cell和storyboard紧密关联。(storyboard的一大特点就是不能拥有独立, 可复用的view)

只需要在storyboard中注册cell。

当我们不需要复用cell时,可以选择此方法

xib文件 + 代码

优点: 可以直观的看到cell的样子。

需要同时管理storyboard和xib文件,有点麻烦。

只需要在代码中注册cell。

当我们需要复用cell时,可以选择此方法。

##demo

纯代码的方式: https://git.oschina.net/iSingular/CustomCellWithPureCode.git

storyboard + 代码: https://git.oschina.net/iSingular/CustomCellWithStoryboard.git

xib + 代码: https://git.oschina.net/iSingular/CustomCellWithXib.git
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: