0

我参与了 TableView 闪烁问题。当我通过 loadmore 在 tableview 中附加数据时,TableView 正在闪烁。如果我使用此代码,那么一切都很好。

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 400;
}

但我正在计算每一行的高度。因为每一行的高度都不一样。然后我正在使用该代码,应用该代码后,我的 TableView 正在闪烁。

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *temp;

if(_buddyWallSection)
    temp =  arrayBuddyList;
else
    temp = arrayMyWallList;

CGFloat height = 320;
if( [[temp objectAtIndex:indexPath.row/2] isKindOfClass:[NSString class]] )
{
    return height;
}
CGSize maximumLabelSize = CGSizeMake(280,9999);
GolferWall *wallComnt = [temp objectAtIndex:indexPath.row/2];
CGSize expectedSize = [[self plainTextFromHTMLText:wallComnt.contentTextHTML]sizeWithFont:[UIFont fontWithName:FontNameArial size:15] constrainedToSize:maximumLabelSize  lineBreakMode:NSLineBreakByWordWrapping];
height = expectedSize.height;

NSLog(@"expected size %f", height);

if(wallComnt.imageNames.count == 0)
   return 130 + ( height);

if ( height < 100 )
{
    height = 350;
}
else
    height = height * 2 ;

return height;
}

请检查一下我遗漏了什么?

谢谢

4

1 回答 1

0

这里的问题是,每次将要显示一行时,您都在执行 cpu 密集型任务。更准确地说,问题出在下面一行:

CGSize expectedSize = [[self plainTextFromHTMLText:wallComnt.contentTextHTML]sizeWithFont:[UIFont fontWithName:FontNameArial size:15] 
constrainedToSize:maximumLabelSize  
lineBreakMode:NSLineBreakByWordWrapping];

解决方案是预先评估该大小,对每个对象进行一次。例如,在您的 GolferWall 类中,您可以添加如下属性:

@property (nonatonic, assign, readonly) CGFloat contentSize;

在 GolferWall 初始化方法中,您可以简单地复制您已经在 tableView:heightForRowAtIndexPath 中编写的代码:

- (instancetype) init
{
    self = [super init];
    *** your init stuff here ***
    self.contentSize = [[self plainTextFromHTMLText:self.contentTextHTML]sizeWithFont:[UIFont fontWithName:FontNameArial size:15] constrainedToSize:maximumLabelSize  lineBreakMode:NSLineBreakByWordWrapping];

    return self;
}

然后在 tableView:heightForRowAtIndexPath: 中只需替换此代码:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *temp;

if(_buddyWallSection)
temp =  arrayBuddyList;
else
    temp = arrayMyWallList;

CGFloat height = 320;
if( [[temp objectAtIndex:indexPath.row/2] isKindOfClass:[NSString class]] )
{
    return height;
}
CGSize maximumLabelSize = CGSizeMake(280,9999);
GolferWall *wallComnt = [temp objectAtIndex:indexPath.row/2];

// The magic is here
CGSize expectedSize = wallComnt.contentSize;
height = expectedSize.height;

NSLog(@"expected size %f", height);

if(wallComnt.imageNames.count == 0)
   return 130 + ( height);

if ( height < 100 )
{
    height = 350;
}
else
    height = height * 2 ;

return height;
}
于 2014-11-06T10:45:41.830 回答