0

总而言之,我面临两个问题,第一个是有时某些单元格会从 tableview 中消失并随机重新出现。第二个是 iPhone 4 及更低版本的滚动性能问题。

第一个问题:

我通过添加子视图 [cell contentView] 在 UITableView 中显示一个简单的元素列表。大多数情况下它运行良好,但有时当我滚动(并且非常随机)时,一个单元格会消失。

因为这个“消失”的单元格被重复使用,所以当我滚动时,重复使用的单元格也将是“空白”。并且在滚动时,一个单元格会再次随机出现/消失。

这是我的 cellForRowAtIndexPath: 方法代码:

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
LBSelectorChampionViewController *item = [self itemAtIndexPath:indexPath];
if (cell == nil) {
    NSLog(@"CELL NIL");
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    [[item view] setTag:99];
    [[item champName] setTag:50];
    [[item champImage] setTag:51];
    [[item buttonFavorite] setTag:52];
    [[cell contentView] addSubview:[item view]];
}

UILabel *championLabel =  (UILabel*)[[[cell contentView] viewWithTag:99] viewWithTag:50];
LBFavoriteChampionButton *buttonFavorite = (LBFavoriteChampionButton*)[[[cell contentView] viewWithTag:99] viewWithTag:52];
UIImageView *championImage = (UIImageView*)[[[cell contentView] viewWithTag:99] viewWithTag:51];

// Text
[championLabel setText:[item displayValue]];

[championImage setImageWithURL:[NSURL URLWithString:[item imageUrl]]];

// Fav button
[buttonFavorite setCurrentChampion:item];
if ([[self favoritesChampions] containsObject:item]) {
    [buttonFavorite setSelected:YES];
    [buttonFavorite setIsFavorite:YES];
} else {
    [buttonFavorite setSelected:NO];
    [buttonFavorite setIsFavorite:NO];
}
return cell;}
}

我尝试记录所有内容,我检查了“item”是否有时可能为空,但事实并非如此。但是当一个单元格消失时,[[[cell contentView] subviews] count]等于0,通常应该是1。我真的不明白这里发生了什么。我在真实设备+模拟器上对其进行了测试,并且它们都发生了。

第二个问题:

我的另一个“问题”是 tableview 的滚动不像我期望的那样在 iPhone 4 上平滑(在 iOS 6 和 iOS 7 上测试,结果相同:-()。我正在使用 SDWebImage 加载图像异步缓存,我正在重复使用单元格,我能做些什么来提高性能?我在 iPhone 4S 上测试过,没有问题,滚动非常流畅。

难道我做错了什么 ?关于我的一个问题的任何想法?

感谢您花时间回答我。

编辑:第一次尝试解决问题

尝试使用自定义 UITableViewCell 子类自定义单元格:

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"LBListChampionCell";

LBListChampionCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil){
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"LBListChampionCell" owner:self options:nil];
    cell = [topLevelObjects objectAtIndex:0];
}
LBSelectorChampionViewController *item = [self itemAtIndexPath:indexPath];
[[cell championName] setText:[item displayValue]];
[[cell championLogo] setImageWithURL:[NSURL URLWithString:[item imageUrl]]];
return cell;
}

我暂时无法重现“消失”错误(有时需要一点时间才能重现它......),但性能方面没有任何改善:(。即使只是设置一个虚拟文本: [[cell ChampionName] setText:@"Test"]; (并评论项目部分)滚动仍然不是很流畅。

有任何想法吗 ?

编辑 2:最佳解决方案(感谢 rdelmar)

创建 UITableViewCell 的子类并在 viewDidLoad 中加载 nib:

- (void)viewDidLoad
{
    ...
    UINib *nib = [UINib nibWithNibName:@"LBListChampionCell" bundle:nil];
    [[self tableView] registerNib:nib forCellReuseIdentifier:@"LBListChampionCell"];
}

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    LBListChampionCell *cell =  [tableView dequeueReusableCellWithIdentifier:@"LBListChampionCell"];
    LBSelectorChampionViewController *item = [self itemAtIndexPath:indexPath];
    [[cell championName] setText:[item displayValue]];
    [[cell championLogo] setImageWithURL:[NSURL URLWithString:[item imageUrl]]];
    ...
}

它提高了滚动性能(在 iPhone 4 上仍然不是很流畅,但效果很好)。此外,似乎没有细胞消失了:-)

谢谢rdelmar!

4

2 回答 2

1

我认为以某种方式LBSelectorChampionViewController *item = [self itemAtIndexPath:indexPath];从您的一个单元格的 contentView 添加到另一个单元格的 contentView,这将导致前一个单元格的 contentView 具有 0 子视图。

于 2013-08-30T15:06:26.010 回答
0

我认为由于单元可重用性,您遇到了第一个问题。LBSelectorChampionViewController *item = [self itemAtIndexPath:indexPath];不会总是添加到 [cell contentView] 因为 cell 可能不是 nil。此外,可能会出现此视图将被添加到另一个单元格并从前一个单元格中删除的情况。无论如何,如果您将 UITableViewCell 子类化并成为此自定义单元格的一部分,这将更容易解决LBSelectorChampionViewController。这将使一切变得更容易,您将永远不会遇到可重用性问题。

我对 SDWebImage 并不十分熟悉,但问题可能在于它不会缓存图像,并且每次[championImage setImageWithURL:[NSURL URLWithString:[item imageUrl]]];被命中时都会尝试加载新图像。我在一些项目中使用AFNetworking来加载图像并且从未遇到任何问题。

希望这有帮助!干杯!

于 2013-08-30T15:21:04.660 回答