向 TableView 填充数据


问题


想要在 TableView 中填充数据。

方案


创建一个遵循 UITableViewDataSource 协议的对象并把它分配到一个 TableView 实例中,然后通过响应数据源消息给你的 TableView 提供信息。

#import <UIKit/UIKit.h>

@Interface TableViewController : UIViewController <UITableViewDataSource>
@property (nonatomic, strong) UITableView *myTableView;
@end

在视图控制器中用 viewDidLoad 方法可以创建 TableView ,然后将 viewController 设置为 tableView 的数据源。

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.myTableView = [[UITableView alloc] initWithFrame: self.view.bounds
style: UITableViewStylePlain];
self.myTableView.dataSource = self;

/* Make sure tableView resize correctly */
self.myTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview: self.myTableView];
}

现在需要确定我们的表视图响应 UITableViewDataSource 协议的 @required 方法,按住键盘上的 command 键,在视图控制器的头文件 UITableViewDataSource 上单击,这将会展示这个协议 @required 修饰的方法。

UITableView 类定义了一个名为 dataSource 的属性,这个非固定类型的对象必须遵循 UITableViewDataSource 协议,每次刷新表格视图,并使用 reloadData 方法重新加载时,这个 TableView 会从其数据源调用各种方法以找出对其填充的数据,一个 TableView 的数据源能够实现三个重要方法,其中2个对每个数据源都要强制执行。

  • numberOfSectionsInTableView: 此方法允许数据源告知加载到 TableView 中的表的 Section 数。

  • tableView:numberOfRowsInSection: 此方法告诉视图控制器有多少单元格或者行要加载到每个 Section, Section 个数传递给数据源中的 numberOfRowsInSection 作参数,这个方法在数据源对象中要强制执行。

  • tableView:cellForRowAtIndexPath: 此方法负责返回作为 TableView 行的 UITableViewCell 类静态实例。这个方法在数据源对象的执行中也是强制性的。

首先,告诉 UITableView 显示3个Section.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSInteger result = 0;

if ([tableView isEqual:self.myTableView]) {
result = 3;
}

return result;
}

然后,告诉 UITableView 需要在每个 Section 显示多少行。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger result = 0;

if ([tableView isEqual:self.myTableView]) {
switch (section) {
case 0: {
result = 3;
break;
}
case 1: {
result = 5;
break;
}
case 2: {
result = 8;
break;
}
}
}
return result;
}

最后,呈现 Cell。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *result = nil;

if ([tableView isEqual:self.myTableView]) {
static NSString *TableViewCellIdentifier = @"MyCells";
result = [tableView dequeueReusableCellWithIdentifier:TableViewCellIdentifier];

if (result == nil) {
result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TableViewCellIdentifier];
}

result.textLabel.text = [NSString stringWithFormat:@"Section %ld, Cell %ld", (long)indexPath.section, (long)indexPath.row];
}

return result;
}

TableView-2

图4-2. 一个包含3个Section空白的TableView

当重新加载或刷新TableView,要通过UITableViewDataSource协议查询数据源,请求许多的信息。

TableView首先请求Section的个数,每个Section来负责持有行或cells。数据源确认了Section数目之后,TableView会为每个Section请求行数,数据源获取每个Section的从零开始的索引,并基于这一点,可以决定多少cells已加载到每个Section。

确定了每个Section的cells数目之后,TableView继续请求数据源以展示每个Section的每个cells,可以分配UITableViewCell类的实例并把其返回TableView。当然,每个cells可以设置的属性有很多,属性中包括标题,子标题,cells的颜色以及更多。