storyboard在可视化设计tableview和tableview的cell的时候非常方便.但是有些人早期可能是从手写代码控件过来的,所以这里有一些需要注意的地方.
1. 不能使用registerClass
2. 无需判断dequeueReusableCellWithIdentifier forIndexPath返回空cell的情况,因为一定会返回非空,并且子类化后的cell不要写initWithStyle了.
3. cell被重用如何提前知道? 重写cell的prepareForReuse
----------分割线,后面是具体解释---------------------------
1. 不能使用registerClass
当我们在storyboard方式使用UITableView时候, UITableViewCell不能使用registerClass注册.
通常在ios6中使用UITableView时候手写代码方式,会在viewDidLoad用如下方式注册重用标识.
[self.tableView registerClass:[RecipeBookCell class] forCellReuseIdentifier:@"RecipeCell"];
因为这种方式是给纯手工方式使用的. 当你使用这个registerClass注册之后,在storyboard中画的Dynamic Prototypes就不再生效了.
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //注意当在storyboard中使用这里不能注册,也无需注册,storyboard会自动注册//[self.tableView registerClass:[RecipeBookCell class] forCellReuseIdentifier:@"RecipeCell"]; }
2. 无需判断dequeueReusableCellWithIdentifier forIndexPath返回空cell的情况,因为一定会返回非空,并且子类化后的cell不要写initWithStyle了.
另一个需要注意的地方是,在手写代码的方式中,通常会判断 tableView dequeueReusableCellWithIdentifier forIndexPath返回的cell是否为空,如果为空则调用alloc和initWithStyle. (也就是如果前面使用了registerClass,则需要这个判断)
而在使用了storyboard的Dynamic Prototypes之后,这里永远都不会调用了.因为dequeueReusableCellWithIdentifier forIndexPath从来不会返回等于nil的cell给你.
同时这也就表示,你的UITableViewCell子类化之后initWithStyle不会被调用,你也就不要费心在里面写代码了.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *simpleTableIdentifier = @"RecipeCell"; RecipeBookCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier forIndexPath:indexPath]; if (cell == nil) { //NSLog(@"如果不用registerClass则每次都不会走这里"); //cell = [[RecipeBookCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:simpleTableIdentifier]; }
//这里是在storyboard中画的控件,在头文件中关联即可,无需在cell的init方法中初始化,直接用就行
cell.nameLabel.text = [tableData objectAtIndex:indexPath.row]; cell.thumbnailImageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]]; cell.prepTimeLabel.text = [prepTime objectAtIndex:indexPath.row]; return cell; }
3. cell被重用如何提前知道? 重写cell的prepareForReuse
官方头文件中有说明.当前已经被分配的cell如果被重用了(通常是滚动出屏幕外了),会调用cell的prepareForReuse通知cell.
注意这里重写方法的时候,注意一定要调用父类方法[super prepareForReuse] .
这个在使用cell作为网络访问的代理容器时尤其要注意,需要在这里通知取消掉前一次网络请求.不要再给这个cell发数据了.
// if the cell is reusable (has a reuse identifier), this is called just before the cell is returned from the table view method dequeueReusableCellWithIdentifier:. If you override, you MUST call super. - (void)prepareForReuse { [super prepareForReuse]; NSLog(@"prepareForReuse: %@",_nameLabel.text); }