1.UITableViewDelegate
UITableView类定义了一个名为delegate的属性,Table View可以把这个属性分配给一个遵循 UITableViewDelegate 协议的对象;换句话说,这个委托必须保证回应此协议中定义的消息,这些消息通过Table View本身发送到委托对象。把Table View的委托看作是收听由Table View发送各种事件的对象,例如当一个单元格被选中,或者当一个Table View要指出它的单元格的高度。某种程度上,我们也可以使用 Interface Builder 来修正 Table View及其单元格的视图外观。只要打开 Interface Builder,选择一个你之前创建的 Table View,然后选择Tools→Size Inspector;在Size Inspector板,可以通过改变Table View单元格的的高度值就可以修改 Table View 的视觉外观。
为了使你选择的Table View的委托对象符合UITableViewDelegate协议,你需要通过下面的办法把协议增加到对象的接口声明中
#import <UIKit/UIKit.h>
@interface MyViewController : UITableViewController<UITableViewDelegate>
@property(nonatomic,strong)UITableView *mytableView;
@end
于那些 UITableViewDelegate 协议带有@required 标记的消息要强制委托对象回应。可以选择性的回应其他消息,但是委托必须回应任何一条你想影响 Table View 的消息。
发送到一个 Table View 的委托对象的消息将携带一个参数,这个参数会告诉委托对象哪个 Table View 发出的消息;注意到这一点非常重要,因为在特定情况下你需要在一个对象(通常是视图)中放置超过一张 Table View。因为这一点,极力推荐你做出的决定是基于事实上向你的委托对象发送确切消息的 Table View ,比如
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat ret = 20.0f;
if([tableView isEqual:self.mytableView])
{
ret = 40.0f;
}
return ret;
}
值得注意的是 Table View 中单元格的位置由其 indexpath 表示的。一个索引路径是section 和 row 索引的组合;section 索引是从零开始的并指定每个单元格属于哪个分组或Section,而在 section 中的单元格索引又是从零开始的。
2.UITableViewDataSource
创建一个遵循 UITableViewDataSource 协议的对象并把它分配到一个 Table View 实例中;然后通过响应数据源消息给你的 Table View提供信息。举个例子,我们来看下,在我们的视图控制器中声明.h 文件,这个文件随后会在其视图中创建一个 Table View,看下代码:
#import <UIKit/UIKit.h>
@interface MyViewController : UITableViewController<UITableViewDelegate,UITableViewDataSource>
@property(nonatomic,strong)UITableView *mytableView;
@end
并且将
viewcontroller 设置为 table view 的数据源:
现在我们需要确定我们的表视图响应 UITableViewDataSource 协议的@required 方法,按住键盘上的 command 键,在视图控制器的头文件的 UITableViewDataSource 上单击,这将会展示给你这个协议@required 修饰的方法。
UITableView 类定义了一个名为 dataSource 的属性,这个非固定类型的对象必须遵循UITableViewDataSource 协议,每次刷新表格视图,并使用 reloadData 方法重新加载时,这个 Table View 会从其数据源调用各种方法以找出你打算对其填充的数据,一个 Table View的数据源能够实现三个重要方法,其中 2 个对每个数据源都要强制执行:
numberOfSectionsInTableView:此方法允许数据源告知加载到 Table View 中的表的 Section 数。
tableView:numberOfRowsInSection:
此方法告诉视图控制器有多少单元格或者行要加载到每个 Section,Section 个数传递给数据源中的 numberOfRowsInSection 作参数,这个方法在数据源对象中要强制执行。
tableView:cellForRowAtIndexPath:
此方法负责返回作为 Table View 行的 UITableViewCell 类静态实例。这个方法在数据源对象的执行中也是强制性的。
下面我们在视图控制器中实现一下这些方法。首先告诉 TableView 显示 3个 sections:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSInteger ret = 0;
if([tableView isEqual:self.mytableView])
{
ret = 3;
}
return ret;
}
然后告诉表视图需要它在每个 Section 显示多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger ret = 0;
if([tableView isEqual:self.mytableView])
{
switch (section) {
case 0:
ret = 3;
break;
case 1:
ret = 5;
break;
case 2:
ret = 8;
break;
default:
break;
}
}
return ret;
}
现在要求 TableView 首先呈现 3 个 Section,第一个 Section3 行;第二个Section5行,第三个Section8行。然后呢?返回TableViewcell的静态实例给tableview,我们想要 tablview 呈现的 cells 如下
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:@"Section %ld,Cell %ld",(long)indexPath.section,(long)indexPath.row];
return cell;
}
如果在模拟器中运行程序 ,效果是这样的
当重新加载或刷新Table View,要通过UITableViewDataSource协议查询数据源,请求许多的信息。在前面