先谈基础:
1.TableViewCell系统自定义样式:在默认UITableViewCell分别有contentview和accessoryView这两个subview.其中contentview的默认有3个子视图,两个UILab(分别由textLabel和detailTextLabel属性访问)和一个UIImageView(由imageView属性访问),这三个子视图是否显示以及具体位置由UITableViewCell的样式类型决定,该样式类型是一个枚举类型:
typedef enum : NSInteger {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
} UITableViewCellStyle;
在UITableViewCell的初始化方法(initWithStyle:reuseIdentifier:)中,第一个参数传入的便是该枚举类型的值,具体这四种自带样式是怎么影响前面所说的三个子视,百度一下便知.而accessoryView则是由UITableViewCell的accessoryType属性和accessoryView属性来决定,后者优先级高(即如果同时设置了这两个属性,那么最终accessoryView的效果由后者来决定),其中accessoryType属性是一个枚举类型
typedef enum : NSInteger {
UITableViewCellAccessoryNone,
UITableViewCellAccessoryDisclosureIndicator,
UITableViewCellAccessoryDetailDisclosureButton,
UITableViewCellAccessoryCheckmark,
UITableViewCellAccessoryDetailButton
} UITableViewCellAccessoryType;
,具体每种枚举值是怎样一个accessoryView的效果,百度便知,而accessoryView属性则是可以任意UIView控件,比如iphone设置界面中飞行模式那个Cell,后面跟的是一个开关类型的accessoryVIew,但是accessoryType属性中的所有枚举值均没有这种效果,所以此时你便可以直接新建一个UISwitch控件的类型的对象,然后将accessoryVIew属性赋值为该对象.
2.TableViewCell的重用机制:关于这点,网上查了很多资料,看了之后,说说我自己的理解,在TableView中,每次将原先未显示的Cell拉入到显示区域,这时就会重新调用(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法来获取该Cell的对象,如果你在该方法中仅仅只是普通地创建UITableViewCell对象,然后配置好返回的话,那么有可能就会申请创建了很多很多对象,即使你这个TableView总的UITableViewCell数量不多,但是如果你反复上下拖动,,那么每次新进入到显示区的UITableViewCell都会调用一次上面所说的方法创建一个UITableViewCell对象,后果不堪设想,所以解决的办法就是为某一类相同样式的UITableViewCell定义一个标识,然后在上面的方法中不直接创建UITableViewCell对象,而是调用UITableView的dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath的方法来重用UITableViewCell对象,然后重新配置,这样就不会有很多UITableViewCell对象被创建占内存了,比如某个TableView显示区域同时只能显示5个UITableViewCell,当用户往下拖动第6个UITableViewCell出现在显示区域,此时因为在TableVIew的缓存资源池中没有UITableViewCell对象,所以这时会新创建一个UITableViewCell对象(新创建对象需由开发者自己用代码写,但是如果在storyboard中已经定义该种标识的UITableViewCell,那么dequeueReusableCellWithIdentifier便能自动创建,不需要人为写代码创建,下面示例代码会说明),但是此时因为第一个UITableViewCell对象已经不在显示区域中了,所以该对象会被放入TableView对象的资源池中,当用户继续往下滚或者往上回滚的话,那么新进入到显示区的UITableViewCell在执行(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法的时候不会再创建对象,而是复用了前面资源池中已有的那个对象,然后重新配置,然后显示.示例代码如下:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//若在storyboard中已经定义了有标识的UITableViewCell,那么这句话可以省略
static NSString *ID=@"ID";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
//若在storyboard中已经定义了有标识的UITableViewCell,那么这句话可以省略
//因为storyboard中若有对应UITableViewCell,那么执行dequeueReusableCellWithIdentifier,若资源池没可用UITableViewCell会自动创建.不可能返回nil
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
//3.配置该行cell的数据
.........
//4.返回cell
return cell;
}
3.关于UITableViewController 类,UITableViewDataSource代理,UITableViewDelegate代理的分析
这里就简单讲一下,平常大家在设计的时候基本都让自定义的TableViewController(继承于UITableViewController)实现相应的UITableViewDataSource和UITableViewDelegate协议,从而使自定义的TableViewController同时也作为该Table的data source和delegate,前面所用的(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath其实是UITableViewDataSource协议中的方法,而非UITableViewController类中的方法.