阅读了很久的文档,终于可以开始动手实践了~
首先,创建一个Empty Application类型的Project,名字的话可以根据自己的爱好随意起名。在此处,我将project命名为TableViewDemo。
相信大家在学习客户端的时候,常听说MVC模式。即将数据(Module)、视图(View)和控制(Controller)进行分离,在这里,编者也采用MVC模式,将数据、视图和控制三部分进行分离,创建三个文件和group,创建之后的文档列表如下图所示:
其中,TableViewController继承了UITableViewController,并且适应协议UITableViewDataSource,UITableViewDelegate。该类为控制部分,进行页面和table view的控制。另外,ItemModel是数据部分,存储了将展现在tableCell上的数据信息。最后是TableCell继承了UITableViewCell,其作为table view的cell显示部分。
好了,现在做好了所有的准备,就可以开始激动人心的编码了。
Step1 TableViewController注册
找到AppDelegate.m文件,在application:didFinishLaunchingWithOptions:方法,为window添加rootViewController。同时,需要将controller的view添加到window内。具体实现如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = [[TableViewController alloc] initWithNibName:nil bundle:nil];
[self.window addSubview:self.window.rootViewController.view];
[self.window makeKeyAndVisible];
return YES;
}
Step2 数据的创建
在Demo中,编者将创建具有三个control的cell,即:标题,价格和图片。因此在ItemModel类中,需要定义存储这三种数据的属性:
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *price;
@property (nonatomic, copy) NSString *imageName;
【注】为了能够让其他类能够在外部访问这些变量,应该将属性的定义写在头文件中。
Step3 table cell的创建
前面说到,我们将创建具有三个control的cell,为了显示这些信息,将会创建两个label和一个imageView来显示信息。为了对cell更新,将会对外提供一个更新cell的接口。
首先,在头文件TableCell.h中进行control的属性和接口定义:
@interface TableCell : UITableViewCell
@property (strong, nonatomic) UILabel *titleLabel;
@property (strong, nonatomic) UILabel *priceLabel;
@property (strong, nonatomic) UIImageView *imageItemView;
-(void)updateCellWithModel:(ItemModel *)model;
接着,在TableCell.m中进行接口和初始化函数的实现:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
int x = 10, y = 10;
self.imageItemView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 90, 90)];
[self.contentView addSubview:self.imageItemView];
x = x + self.imageItemView.frame.size.width + 10;
self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, y, 180, 60)];
self.titleLabel.numberOfLines = 0;
self.titleLabel.lineBreakMode = NSLineBreakByCharWrapping;
[self.contentView addSubview:self.titleLabel];
y = y + self.titleLabel.frame.size.height;
self.priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, y, 100, 30)];
self.priceLabel.textColor = [UIColor redColor];
[self.contentView addSubview:self.priceLabel];
}
return self;
}
-(void)updateCellWithModel:(ItemModel *)model
{
self.imageItemView.image = [UIImage imageNamed:model.imageName];
self.titleLabel.text = model.title;
self.priceLabel.text = [NSString stringWithFormat:@"$ %@", model.price];
}
-(void)awakeFromNib
{
}
-(void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
其中,initWithStyle:reuseIdentifier方法时cell的初始化方法,在该方法中实现了cell显示的基本定义,对control进行了初始化。另外,updateCellWithModel函数主要通过传入的model参数,对cell的三个control的内容进行设置。
Step4 controller的定义
首先,在头文件TableViewController.h中进行属性的定义:
@property (strong, nonatomic) UITableView *testTableView;
@property (strong, nonatomic) NSMutableArray *list;
接着,在TableViewController.m中实现tableView的基本操作。其中,对UITableViewDataSource协议的实现有两个必须要实现的方法(在UITableViewDataSoure的博文中查看详细信息):tableView:cellForRowAtIndexPath:和tableView:numberOfRowsInSection:。具体实现如下:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(@"[tableView:numberOfRowsInSection] is called:%d",section);
return self.list.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"[tableView:cellForRowAtIndexPath] is called:[%d,%d]",indexPath.section, indexPath.row);
TableCell *cell = [tableView dequeueReusableCellWithIdentifier:tableCellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[TableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableCellIdentifier];
}
ItemModel *model = [self.list objectAtIndex:indexPath.row];
[cell updateCellWithModel:model];
return cell;
}
此外,还需要对table每一行的高度和是否可编辑进行定义,具体实现如下:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"tableView:heightForRowAtIndexPath is called:[%d,%d]", indexPath.section, indexPath.row);
return 110;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"[tableView:canEditRowAtIndexPath] is called:[%d,%d]",indexPath.section, indexPath.row);
return YES;
}
然后,利用懒加载机制,对属性进行初始化:
-(UITableView *)testTableView{
if (!_testTableView) {
//plain 类型
_testTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 20,[UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 20) style:UITableViewStylePlain];
_testTableView.delegate = self;
_testTableView.dataSource = self;
}
return _testTableView;
}
-(NSMutableArray *)list
{
if (!_list) {
_list = [[NSMutableArray alloc] init];
}
return _list;
}
最后,定义一个增加data的函数,并在viewDidLoad方法中进行调用,从而增加数据:
- (void)viewDidLoad
{
NSLog(@"viewDidLoad is called!");
[super viewDidLoad];
[self.view addSubview:self.testTableView];
[self addData:10];
}
-(void)addData:(NSInteger)num
{
for (int i = 0; i < num; ++i) {
GameItemModel *itemModel = [[GameItemModel alloc] init];
itemModel.imageName = @"game.png";
itemModel.title = @"极致体验,3D特效,精彩剧情,尽在福尔摩斯";
itemModel.price = [NSString stringWithFormat:@"30%d.00",i];
[self.dataArray addObject:itemModel];
}
}
当然,关于图片资源,随意找一个添加到工程中,然后将名字填写到addData的imageName中即可。
Step5 运行程序
到此为止,TableViewDemo就编写完毕了。这是编者写的第一个tableView,虽然略显粗糙,但是还是很容易上手的。