UITableViewCell在iPhone 4上随机消失+滚动性能问题

时间:2013-08-30 14:54:39

标签: iphone ios objective-c uitableview

总而言之,我面临着两个问题,第一个问题是,一些细胞从桌面视图中消失并随机重新出现。第二个是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”是否有时可能为null而且从来都不是这样。但是当一个单元格消失时,[[[cell contentView] subviews] count]等于0,通常应为1。 我真的不明白这里发生了什么。我在真实的设备+模拟器上进行了测试,并且两者都发生了。

2nt问题:

我的另一个“问题”是桌面视图的滚动不如我想象的那样顺利在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!

2 个答案:

答案 0 :(得分:1)

我认为来自你的一个单元格contentView的LBSelectorChampionViewController *item = [self itemAtIndexPath:indexPath];被添加到另一个单元格的contentView中,这会导致前一个单元格的contentView有0个子视图。

答案 1 :(得分:0)

我认为你因为细胞可重用性而遇到了第一个问题。 LBSelectorChampionViewController *item = [self itemAtIndexPath:indexPath];并不总是被添加到[cell contentView],因为单元格可能不是nil。此外,可能存在将此视图添加到另一个单元格并从之前删除的情况。无论如何,如果您继承UITableViewCell并使LBSelectorChampionViewController成为此自定义单元格的一部分,这将更容易修复。这将使一切变得更容易,您将永远不会遇到可重用性问题。

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

希望这有用! 干杯!