我正在使用表格视图使用自定义编码和标记方法来节省内存。
我成功地在视图中显示数据,但问题是如果显示10个单元格然后如果我向下滚动一个单元格那么它应该显示2-11单元格数据但它再次切换到1-10。 / p>
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UILabel *cellNAMElabl = nil;
UILabel *cellDetaillabl = nil;
UIImageView *imgView = nil;
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
cellNAMElabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 10, 150, 20)];
[cellNAMElabl setTag:1];
cellNAMElabl.text = [name5 objectAtIndex:indexPath.row];
UIFont *myFont1 = [ UIFont fontWithName: @"Arial" size: 20.0 ];
cellNAMElabl.font = myFont1;
[cell.contentView addSubview:cellNAMElabl];
cellDetaillabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 28, 150, 20)];
[cellDetaillabl setTag:2];
cellDetaillabl.text = [email5 objectAtIndex:indexPath.row];
UIFont *myFont = [ UIFont fontWithName: @"Arial" size: 13.0 ];
cellDetaillabl.font = myFont;
[cell.contentView addSubview:cellDetaillabl];
imgView=[[UIImageView alloc] initWithFrame:CGRectMake(25, 5, 52, 50)];
[imgView setTag:3];
imgView.image = [imagepath5 objectAtIndex:indexPath.row];
[cell.contentView addSubview:imgView];
}
cellNAMElabl = (UILabel *)[cell viewWithTag:1];
cellDetaillabl = (UILabel*)[cell viewWithTag:2];
imgView = (UIImageView*)[cell viewWithTag:3];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
答案 0 :(得分:1)
如果已经创建了子视图,则不会将新内容分配给子视图。在案例if(cell == nil)
之后,您刚刚获得了参考资料。
cellNAMElabl = (UILabel *)[cell viewWithTag:1];
cellDetaillabl = (UILabel*)[cell viewWithTag:2];
imgView = (UIImageView*)[cell viewWithTag:3];
这里当cell不是nil时,你只是引用了标签和imageview,但是你没有从数据源设置新的文本和图像。添加以下行并将其从if (cell == nil)
部分删除:
cellNAMElabl.text = [name5 objectAtIndex:indexPath.row];
cellDetaillabl.text = [email5 objectAtIndex:indexPath.row];
imgView.image = [imagepath5 objectAtIndex:indexPath.row];
[cell.contentView addSubview:imgView];
答案 1 :(得分:1)
此dequeueReusableCellWithIdentifier
的工作方式:如果iOS检测到单元格不再显示,则dequeueReusableCellWithIdentifier
将返回该单元格。如果没有未使用的单元格,则返回nil。那么你需要做什么:
如果dequeueReusableCellWithIdentifier
返回nil,则创建一个新单元格,然后执行具有相同标识符的所有单元格所需的所有设置。例如,像你一样添加视图标签,设置字体,颜色等。
然后,无论您使用dequeueReusableCellWithIdentifier
返回的单元格还是您刚刚创建的单元格,都可以添加用于要显示的特定部分/行的所有信息。因此,如果第1行,第2行等显示不同的文本,则在此处设置文本。这就是你没有做的,所以当一个单元被重用时,你没有为它设置新的文本。
所以我们的想法是,所有行的所有工作都只在创建一个单元格时一次完成,并且只创建了所需数量的单元格,以便在屏幕。根据需要,每行都会执行不同行的工作。
答案 2 :(得分:0)
你想要做的是......
如果单元格为nil,则添加/设置tableViewCell UI。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
UILabel *cellNAMElabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 10, 150, 20)];
cellNAMElabl.tag = 1;
cellNAMElabl.font = [UIFont fontWithName: @"Arial" size: 20.0 ];
[cell.contentView addSubview:cellNAMElabl];
UILabel *cellDetaillabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 28, 150, 20)];
cellDetaillabl.tag = 2;
cellDetaillabl.font = [UIFont fontWithName: @"Arial" size: 13.0 ];
[cell.contentView addSubview:cellDetaillabl];
UIImageView *imgView=[[UIImageView alloc] initWithFrame:CGRectMake(25, 5, 52, 50)];
imgView.tag = 3;
[cell.contentView addSubview:imgView];
}
//and just update your data if the cell is currently exist and not nil..
//you already called the view using tag so, you dont need those:
// UILabel *cellNAMElabl = nil;
// UILabel *cellDetaillabl = nil;
// UIImageView *imgView = nil;
((UILabel *)[cell viewWithTag:1]).text = [name5 objectAtIndex:indexPath.row]; // cellNAMElabl
((UILabel*)[cell viewWithTag:2]).text = [email5 objectAtIndex:indexPath.row]; // cellDetaillabl
((UIImageView*)[cell viewWithTag:3]).image = [imagepath5 objectAtIndex:indexPath.row]; // imgView
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
希望这对你有所帮助,快乐的编码欢呼!
答案 3 :(得分:0)
如果你在if cell == nil块中设置一个断点,如果你的reuseID正确,它可能只会被第一组命中。这就是为什么它永远不会有机会将任何新数据设置到单元格中。
您不应该查找nil单元格,而是在IB中使用正确的reuseID和原型单元格,该单元格设置为您创建的自定义UITableViewCell子类。
在自定义单元格上实施prepareForReuse
也是一种很好的做法,您可以在其中清除任何单元格数据,例如label.text = nil, imageview.image = nil
这样您就不会从先前出列的单元格中获取无效数据。它可能无法直接解决问题,但它会擦除if cell == nil块中的固定数据集以帮助调试。