首页 文章

自定义UITableViewCell作为委托 - UI元素意外地被重用

提问于
浏览
0

我创建了一个自定义 UITableViewCell ,每个单元格都从 UITableViewController 传递 AVPlayer 对象的自定义子类 . 在每个单元格上,我有一个播放按钮,暂停按钮和加载指示器 .

当我播放音频时,元素按需要工作,并在播放器状态改变时改变,例如播放时,出现暂停按钮,播放按钮消失 . 当我在第二个单元格上播放音频时,第一个单元格知道这一点,重置它的按钮状态,第二个单元格完成它的业务 .

所以这个功能完美无缺,唯一的问题是因为 UITableViewCell 被重用,当我向下滚动到下面的单元格时,我开始看到它们上面出现暂停按钮 . 这是因为它们与上面的单元格相同(重用),并且因为我的单元格是 AVPlayer 的自定义子类的委托,所以音频播放器正在向不正确的单元格发送消息 .

我该怎么做才能使 UITableViewCell 为我的 AVPlayer 单独的委托对象?

3 回答

  • 0

    您必须在重用时从单元格中删除元素:

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    } else {
        /* prepare for reuse */
        [cell.playButton removeFromSuperview];
        /* or */
        [[cell viewWithTag:10] removeFromSuperview];
    }
    
  • 1

    我从JSON blob加载的图像遇到了同样的问题 . 我使用GCD并将我的图像保存到NSDictionary中,并与分配给每个单元格的密钥配对 .

    - (UIImage *)imageForRowAtIndexPath:(NSIndexPath *)indexPath
    {    
        // get the dictionary for the indexPath
        NSDictionary *tweet = [tweets objectAtIndex:[indexPath row]];
    
        // get the user dictionary for the indexPath
        NSDictionary *user = [tweet objectForKey:@"posts"];
    
        //get the image URL
        NSURL *url = [NSURL URLWithString:[[[[[tweet objectForKey:@"photos"] objectAtIndex:0] objectForKey:@"alt_sizes"] objectAtIndex:3] objectForKey:@"url"]];
    
        // get the user's id and check for a cached image first
        NSString *userID = [user objectForKey:@"id"];
        UIImage *image = [self.images objectForKey:userID];
        if(!image)
        {
    
            // if we didn't find an image, create a placeholder image and
            // put it in the "cache". Start the download of the actual image
            image = [UIImage imageNamed:@"Placeholder.png"];
            [self.images setValue:image forKey:userID];
    
            //get the string version of the URL for the image
            //NSString *url = [user objectForKey:@"profile_image_url"];
    
            // create the queue if it doesn't exist
            if (!queue) {
                queue = dispatch_queue_create("image_queue", NULL);
            }
    
            //dispatch_async to get the image data
            dispatch_async(queue, ^{
    
                NSData *data = [NSData dataWithContentsOfURL:url];
                UIImage *anImage = [UIImage imageWithData:data];
                [self.images setValue:anImage forKey:userID];
                UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    
                //dispatch_async on the main queue to update the UI
                dispatch_async(dispatch_get_main_queue(), ^{
                    cell.imageView.image = anImage;
                });
            });
    
    
        }
    
        // return the image, it could be the placeholder, or an image from the cache
        return image;
    }
    
  • -1

    我通过使 UITableViewController 成为音频播放器的代表解决了这个问题 . 然后将"currently playing"单元的 indexPath 保存到 UITableViewController 中的 @property .

    然后在 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 中我检查indexPath是否与"currently playing"单元格 indexPath 相同,如果是这样设置了"audio playing"按钮,如果没有则设置默认按钮排列 .

    这可以更好地区分单元格,因为您有一个唯一标识符 indexPath 来比较它们 .

相关问题