UITableView数据在滚动时显示多次



我有一个UITableView,其中显示数据,但当它滚动时,数据(UILabel)要么消失,要么一次又一次地添加到彼此之上。如果我每次滚动每个单元格,则交换数据。

这是我的cellForRowAtIndexPath:代码

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *cellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if(cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        // configure the cell's background
        UIImageView *gradient = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"gradient"]];
        [cell.contentView addSubview:gradient];
        // configure the cell's label
        UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 130, 300, 44)];
        // grab a reference to the label's text from the tableData
        nameLabel.text = [name objectAtIndex:indexPath.row];
        nameLabel.textColor = [UIColor blackColor];
        nameLabel.font = [UIFont fontWithName:@"DIN-Bold" size:12];
        nameLabel.backgroundColor = [UIColor clearColor];
        // set the autoReiszing mask -- this way if the label spills over the editing
        // [icon?] then the text will trail off in ...
        nameLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        [cell.contentView addSubview:nameLabel];
        // configure the cell's label
        UILabel *tableTextViewLbl = [[UILabel alloc] initWithFrame:CGRectMake(50, 80, 220, 50)];
        // grab a reference to the label's text from the tableData
        tableTextViewLbl.text = [message objectAtIndex:indexPath.row];
        tableTextViewLbl.textColor = [UIColor blackColor];
        tableTextViewLbl.font = [UIFont fontWithName:@"DIN" size:10];
        tableTextViewLbl.backgroundColor = [UIColor clearColor];
        tableTextViewLbl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        [cell.contentView addSubview:tableTextViewLbl];
        // configure the cell's label
        UILabel *tableTimeStampViewLbl = [[UILabel alloc] initWithFrame:CGRectMake(50, 30, 200, 50)];
        // grab a reference to the label's text from the tableData
        tableTimeStampViewLbl.text = [timeStamp objectAtIndex:indexPath.row];
        tableTimeStampViewLbl.textColor = [UIColor lightGrayColor];
        tableTimeStampViewLbl.font = [UIFont fontWithName:@"DIN" size:7];
        tableTimeStampViewLbl.backgroundColor = [UIColor clearColor];
        tableTimeStampViewLbl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        [cell.contentView addSubview:tableTimeStampViewLbl];
    //   UIImageView *image;
    //   UIImage *image1=[UIImage imageNamed:@"rest.png"];
    //   image=[[UIImageView alloc]initWithImage:image1];
    //   image.frame=CGRectMake(10,30,40,30);
    //   
    //   [cell.contentView addSubview:image];
    //

        return cell;
    }

每次将单元格加载/重新加载到视图中时,都要创建一个UILabel实例。事情并非如此。相反,将UILabel作为属性(可能是IBOutlet)添加到UITableView子类中,并在cellForRowAtIndexPath:中对其进行更改。

因此,您将有一个新的类,继承自UITableViewCell——让我们称之为MyCustomCell。

在MyCustomCell.h:中

@interface MyCustomCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@end

MyCustomCell.xib将定义UILabel的位置和配置,当然需要与nameLabel属性相关联。

在cellForRowAtIndexPath中,您只需引用cell.nameLabel并更改文本,而不是实例化新的UILabel。请确保在接口生成器中为单元类定义一个resumeIdentifier,并使用实例化它

MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];
if (!cell) {
    cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyIdentifier"];
}

只需添加以下代码

NSArray *subviews = [[NSArray alloc] initWithArray:cell.contentView.subviews];
for (UILabel *subview in subviews)
{
     [subview removeFromSuperview];
}
[subviews release];
subviews = nil; 

之后

if (cell == nil)
{
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault        reuseIdentifier:CellIdentifier];
} 

然后添加您的代码。

在你遵循我的答案之前,我想告诉你,下面的代码不利于内存管理,因为它会为UITableView的每一行创建新的单元格,所以要小心。

但最好使用,当UITableView具有有限的行(大约50-100行)时,下面的代码对您的情况很有帮助,如果适合您,请使用它。

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *CellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.section,indexPath.row];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell == nil)
    {
        cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
         /// Put your code here
     }
    return cell;
}

如果您的行数有限,那么这是最适合您的代码。

首先,您需要了解UITableView是如何工作的。实际上,UItableView Cell的概念是,每次滚动表视图时,并不是为您创建新的单元格,它只是在cellIdentifier的帮助下重用该单元格

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];这一次我们只需要更新cell的数据。就是这样,简直更好。你可以在下面看到:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *cellIdentifier = @"Cell";
    UILabel *nameLabel = nil;
    UILabel *tableTextViewLbl= nil;
    UILabel *tableTimeStampViewLbl= nil;
    //Here we are , reuse the cells...
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        // configure the cell's background
        UIImageView *gradient = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"gradient"]];
        [cell.contentView addSubview:gradient];
        // configure the cell's label
        nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 130, 300, 44)];
        // grab a reference to the label's text from the tableData
        nameLabel.textColor = [UIColor blackColor];
        nameLabel.font = [UIFont fontWithName:@"DIN-Bold" size:12];
        nameLabel.backgroundColor = [UIColor clearColor];
        nameLabel.tag = 111;//Giving this component to tag so we can access it
        // set the autoReiszing mask -- this way if the label spills over the editing
        // [icon?] then the text will trail off in ...
        nameLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        [cell.contentView addSubview:nameLabel];
        // configure the cell's label
        tableTextViewLbl = [[UILabel alloc] initWithFrame:CGRectMake(50, 80, 220, 50)];
        tableTextViewLbl.textColor = [UIColor blackColor];
        tableTextViewLbl.font = [UIFont fontWithName:@"DIN" size:10];
        tableTextViewLbl.backgroundColor = [UIColor clearColor];
        tableTextViewLbl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        tableTextViewLbl.tag = 222;//Giving this component to tag so we can access it
        [cell.contentView addSubview:tableTextViewLbl];
        // configure the cell's label
        tableTimeStampViewLbl = [[UILabel alloc] initWithFrame:CGRectMake(50, 30, 200, 50)];
        tableTimeStampViewLbl.textColor = [UIColor lightGrayColor];
        tableTimeStampViewLbl.font = [UIFont fontWithName:@"DIN" size:7];
        tableTimeStampViewLbl.backgroundColor = [UIColor clearColor];
        tableTimeStampViewLbl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        tableTimeStampViewLbl.tag = 333;//Giving this component to tag so we can access it
        [cell.contentView addSubview:tableTimeStampViewLbl];
    }

    nameLabel = (UILabel*)[cell.contentView viewWithTag:111];//Here we access the name label with the help of tag, is that we have assigned tag while making the componant.
    nameLabel.text = [name objectAtIndex:indexPath.row];

    tableTextViewLbl = (UILabel*)[cell.contentView viewWithTag:222];//Here we access the name label with the help of tag, is that we have assigned tag while making the componant.
    // grab a reference to the label's text from the tableData
    tableTextViewLbl.text = [message objectAtIndex:indexPath.row];

    tableTimeStampViewLbl = (UILabel*)[cell.contentView viewWithTag:333];//Here we access the name label with the help of tag, is that we have assigned tag while making the componant.
    // grab a reference to the label's text from the tableData
    tableTimeStampViewLbl.text = [timeStamp objectAtIndex:indexPath.row];

    return cell;
}

使用这种方式

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
else{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

但使用自定义单元格是最好的答案。选中此链接可为自定义单元格提供最佳解决方案

最新更新