在UITableViewCell完全可见时播放video

我有一个包含videoURL的数组,我想在UITableviewcell完全可见时播放这些video。

我已经试过了

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView { NSArray* cells = homeTabl.visibleCells; for (HomeCell* cell in cells) { if (cell.frame.origin.y > offset.y && cell.frame.origin.y + cell.frame.size.height < offset.y + bounds.size.height) { NSIndexPath *path = [homeTabl indexPathForCell:cell] ; index = path.row; fullvisible = YES; [homeTabl reloadData]; } else { fullvisible = NO; } } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (fullvisible) { NSURL *url = [NSURL URLWithString:[[responsearray objectAtIndex:indexPath.row]valueForKey:@"feed_video"]]; cell.videoItem = [AVPlayerItem playerItemWithURL:url]; cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem]; cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer]; cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; [cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil]; [cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; cell.avLayer.frame = CGRectMake(5, 9, 310, 310); [cell.contentView.layer addSublayer:cell.avLayer]; [cell.videoPlayer play]; [cell.contentView addSubview:cell.videoActivity]; } else { cell.videoPlayer = nil; [cell.avLayer removeFromSuperlayer]; cell.videoItem = nil; [cell.videoPlayer pause]; } } 

这工作正常 – 但它可怕的减慢表视图的滚动。 请build议我一些其他更好的方法。

您可以使用

 -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { isScrolling = NO; [homeTabl reloadData]; } -(void)scrollViewWillBeginDragging:(UIScrollView *)aScrollView { isScrolling = YES; [homeTabl reloadData]; index = -1; } 

并在cellForRowatindexpath

 if (fullvisible && index == indexPath.row) { if (!isScrolling) { NSLog(@"video index---%d",indexPath.row); if (index == indexPath.row) { NSLog(@"video index---%d",indexPath.row); cell.videoActivity.hidden = NO; // if (index == indexPath.row) { NSURL *url = [NSURL URLWithString:[[responsearray objectAtIndex:indexPath.row]valueForKey:@"feed_video"]]; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(queue, ^{ cell.videoItem = [AVPlayerItem playerItemWithURL:url]; dispatch_sync(dispatch_get_main_queue(), ^{ cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem]; cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer]; cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; [cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil]; [cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; cell.avLayer.frame = CGRectMake(5, 9, 310, 310); [cell.contentView.layer addSublayer: cell.avLayer]; [ cell.videoPlayer play]; [cell.contentView addSubview:cell.videoActivity]; }); }); // } // else{ // cell.videoActivity.hidden = YES; // cell.videoPlayer = nil; // [cell.avLayer removeFromSuperlayer]; // cell.videoItem = nil; // [cell.videoPlayer pause]; // } } }} else{ cell.videoActivity.hidden = YES; cell.videoPlayer = nil; [cell.avLayer removeFromSuperlayer]; cell.videoItem = nil; [cell.videoPlayer pause]; } 

您在主线程中同义加载video项目; 这意味着您的video项正在被下载,并在表格视图单元格被创build的同时加载到表格视图单元格中。 这导致问题,使滚动非常缓慢和缓慢。 要解决这个问题,你需要在一个单独的线程中asynchronous加载你的video。

因此,必须避免同步加载图像,而是使用除主线程以外的其他线程来asynchronous加载图像,以便滚动和加载+显示图像可以独立完成,避免任何forms的延迟。

这可能是一个重复的问题,因为它已经被问及有教程,但由于我自己总是有一个问题(但图片)在我的第一个iOS应用程序,发现它很混乱,我张贴在这里回答,希望有帮助。

尝试移动所有与video加载/显示相关的行,特别是在你的- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath: 。 也做search和阅读其他职位关于“asynchronousvideo加载在表视图单元格”。 这里有很多深入的教程和Q / A。

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(queue, ^{ cell.videoItem = [AVPlayerItem playerItemWithURL:url]; dispatch_sync(dispatch_get_main_queue(), ^{ cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem]; cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer]; cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; [cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil]; [cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; cell.avLayer.frame = CGRectMake(5, 9, 310, 310); [cell.contentView.layer addSublayer: cell.avLayer]; [ cell.videoPlayer play]; [cell.contentView addSubview:cell.videoActivity]; }); }); 

避免每次播放video时重新加载表格视图。 您可以在可见单元格上执行video播放代码,而无需重新加载整个桌面视图。

此外,我怀疑你真的不想播放video,直到表视图停止滚动。 请参阅如何检测UIScrollView何时完成滚动 (检测UIScrollView何时完成滚动令人惊讶不直观)。

如果你真的想在滚动视图停止滚动之前开始播放video,至less要修改你的代码来检查可见单元格是否已经在播放,那么什么也不做。 现在你的tableView:cellForRowAtIndexPath:播放video的代码被执行许多次,每当一个单元格是完全可见的(我怀疑发生了很多!)。