UITableView reloadData没有重新加载表,但UITableView reloadSections工作

时间:2015-12-15 20:05:56

标签: ios objective-c uitableview

我在父UIView中嵌入了一个UITableView。我有一个CustomUITableViewController类设置为tableview的委托和数据源。 在某个后台操作之后,我得到一个更新的对象数组,以便在tableview中显示。

当我更新数据源数组并调用tableview.reloadData方法时,tableview不会刷新。如果我滚动tableview,它只会刷新。

但是,如果我按如下方式调用API:

tableview.beginUpdates - > tableview.reloadSections - > tableview.endUpdates,

它完美运行并立即重新加载表格。 问题是,根据新数据,我必须添加一个新部分,或从tableview中删除旧部分。

因此我无法使用reloadSections API。

有关如何解决这个问题的想法吗?

代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellID = @"tempCell";
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    if (cell == nil) {
        cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
    }
    [cell initializeWithModel:modelsToShow[indexPath.row]];
    return cell;
}
-(void) showModelsInList:(NSMutableArray*) models {
    [modelsToShow removeAllObjects];
    [modelsToShow addObjectsFromArray:models];
    [self setupDataForList];
    [self reloadTable];
}

-(void) reloadTable {
    [self.tableView beginUpdates];
    NSMutableIndexSet* index = [[NSMutableIndexSet alloc]init];
    [index addIndex:0];
    [self.tableView reloadSections:index withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView endUpdates];
   //[self.tableView reloadData]
}

showModelsInList方法是从主线程本身的其他类调用的。

2 个答案:

答案 0 :(得分:0)

初始化表视图单元格的现代方法是注册单元格类(如果单元格在其自己的nib中定义,则为nib)。 viewDidLoad是做这件事的好时机......

// if the cell is a prototype defined in the nib containing the table view, or if
// the cell is built in code in its init method
[self.tableView registerClass:[CustomCell self] forCellReuseIdentifier:@"tempCell"];

// or, if the cell is defined in its own nib
UINib *nib = [UINib nibWithNibName:@"your cell's nib name goes here" bundle:nil];
[_tableView registerNib:nib forCellReuseIdentifier:@"tempCell"];

在上述任何一种情况下,单元格必须在IB或代码中初始化它的“tempCell”标识符。然后,在cellForRowAtIndexPath中,使用方法将单元格出列...

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"tempCell" forIndexPath:indexPath];

无需进一步检查即可查看if (cell == nil)。此版本的dequeue将正常工作(如果某些设置未正确,则会崩溃)。

答案 1 :(得分:0)

我认为,从技术上讲,这是一个错误,但事实是,虽然没有记录,但在重复使用单元格时,您不应该在cellForRowAtIndexPath中重新创建子视图。 / p>

在Interface Builder中设计时创建包含所有所需子视图的单元格。在cellForRowAtIndexPath中更改其位置,大小和其他属性是可以的。

如果您的单元格具有不同的子视图,则每个单元格"键入"应该是自己的班级。创建一个不同的原型单元类,每个类具有不同的标识符,并在单元格出列时简单地使用该标识符。这样,您就可以在cellForRowAtIndexPath中使用正确的单元格类。

要从视图控制器引用其他属性(子视图),只需为每个单元格类型(从UITableViewCell派生)创建类文件。将它分配给IB中的原型UITableViewCell,将视图拖动到.h文件以创建类似于视图控制器的插座,然后在视图控制器中导入该类。

所以,你最终可能得到这样的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (whatever) {
       MyBasicCell *cell = [tableView dequeueReusableCellWithIdentifier:@"basicCell"];
       cell.specialLabel.Text = ...
       return cell;
    } else {
       MyOtherCell *cell = [tableView dequeueReusableCellWithIdentifier:@"otherCell"];
       cell.otherLabel.Text = ...
       return cell;
    }
}