今天在完成一个功能点的时候遇到一个小问题,如题是,在tableview中有多textField表单进行修改操作,在tableview滚动出屏幕时,没保存的textField数据会被刷新为原始指。经过排查,原因是因为进行cell重用和tableview刷新机制引起的(用的是xib布局
)。把问题记录如下:
在使用 故事版时,一般设置在tableview
的 delegate
方法:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
- if(!cell){
- cell = [UITableViewCell alloc]initWithStyle:<#(UITableViewCellStyle)#> reuseIdentifier:<#(nullable NSString *)#>
return cell;
- }
}
-
进行cell的重用。But,在复杂的cell的布局中时,一般都会用到xib进行布局,如果在使用[tableView dequeueReusableCellWithIdentifier:Identifier]
方法进行cell重用时,如上方法已经不能满足,因为每次都会新建一个cell。要进行重用就得使用正确的姿势了。
在viewDidLoad
后注册Nib或者cell。
- (void)viewDidLoad {
[super viewDidLoad];
UINib *nib = [UINib nibWithNibName:NSStringFromClass([CMCardBoxAddNewCardCell class]) bundle:nil];
[self.tableView registerNib:nib forCellReuseIdentifier:Identifier];
}
//在datasource里就不需要注册,直接可重用
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
- if(!cell){
- cell = [UITableViewCell new];//初始化代码
return cell;
- }
或者在delegate
中进行注册
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"Cell";
static BOOL nibsRegistered = NO;
if (!nibsRegistered) {
UINib *nib = [UINib nibWithNibName:NSStringFromClass([Cell class]) bundle:nil];
[tableView registerNib:nib forCellReuseIdentifier:CellIdentifier];
nibsRegistered = YES;
}
Cell *cell = (Cell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.titleLabel.text = [self.dataList objectAtIndex:indexPath.row];
return cell;
}
看上去一切没有问题,cell已经重用了,应该在滚动的时候已经输入到textField里的值不会被重置了吧!已经猜到,还是刷新了!!!因为
tableview还是会去调用delegate进行cell的加载。
所以还是会刷新的。因为新的值在不满足条件下,会被丢弃,不实时的更新。所以猥琐的做了一件事,使用一个临时的变量,保存了输入的值,因为重用了,所以,这个值保存了,检查有值就赋值就可以了!完美!