滚动时 UITableViewCell 的奇怪行为,UIButtons 消失

Odd behaviour with UITableViewCell when scrolling, UIButtons disappearing

我正在尝试在我的自定义 UITableViewCell 中设置一些 UIButton 和 UILabel。对于 table 中的每一行,我有 4 个带有用户个人资料图像的按钮,每个按钮下方是一个显示用户名的标签。图片和用户名取自 Parse.com。我有一个大小为 34 的朋友数组,我显示了 9 行,因此必须隐藏最后两个按钮和标签。下面的代码有效,但由于某种原因,当我向上滚动 table 时,其他一些行也会隐藏它们最右边的两个按钮和标签。我想知道我从数组加载图像的逻辑是否不正确。不确定这里发生了什么。任何建议将不胜感激。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    FriendViewCell *cell = (FriendViewCell *)[tableView dequeueReusableCellWithIdentifier:@"friendCell" forIndexPath:indexPath];

    for (int i = 0; i < 4; i++) {
        if ((int)indexPath.row * 4 + i < [self.currentUser.friends count]) {
            UIButton *button = cell.buttons[i];

            [button setTag:(int)indexPath.row * 4 + i];
            button.layer.cornerRadius = button.frame.size.width / 2;
            button.clipsToBounds = YES;
            UILabel *label = cell.labels[i];
            [button addTarget:self action:@selector(friendTapped:) forControlEvents:UIControlEventTouchUpInside];

            //here we need to decide what to access
            PFUser *user = self.currentUser.friends[(int)indexPath.row * 4 + i];
            label.text = user.username;
            PFFile *userImageFile = user[@"profilePic"];
            [userImageFile getDataInBackgroundWithBlock: ^(NSData *imageData, NSError *error) {
                if (!error) {
                    UIImage *image = [UIImage imageWithData:imageData];
                    [button setBackgroundImage:image forState:UIControlStateNormal];
                }
            }];
        }
        else {
            UIButton *button = cell.buttons[i];
            [button setEnabled:NO];
            [button setHidden:YES];
            UILabel *label = cell.labels[i];
            [label setHidden:YES];
        }
    }
    return cell;
}

您可以尝试在第一次执行时取消隐藏按钮和标签,例如:

if ((int)indexPath.row * 4 + i < [self.currentUser.friends count]) {
     [button setEnabled:YES];
     [button setHidden:NO];
     [label setHidden:NO];
     // Other code
}
else{
......
}

'iOS' 处理此问题的方法是填写自定义单元格的 prepareForReuse 方法。您应该在此处重置缓存系统可能重复使用的单元格的各种属性。

Apple Docs

-prepareForReuse

准备一个可重用的单元格以供 table 视图的委托重用。

讨论

如果 UITableViewCell 对象是可重用的——也就是说,它有一个重用标识符——这个方法会在对象从 UITableView 方法 dequeueReusableCellWithIdentifier: 返回之前被调用。出于性能原因,您应该只重置与内容无关的单元格属性,例如,alpha、编辑和选择状态。 table 视图在 tableView:cellForRowAtIndexPath 中的委托:在重用单元格时应始终重置所有内容。如果单元格对象没有关联的重用标识符,则不会调用此方法。如果覆盖此方法,则必须确保调用超类实现。