TableView单元格video自动播放
我所做的:
当单元格完全可见时,我添加了播放video的代码,当我向下或向上滚动时,再次重新载入tableview并再次播放video。 但是,我的要求是不同的。
我真正想要的是:
我想播放一个video,直到完全可见的向后或向前的单元格。 当用户向下滚动或向上滚动时,不会影响直到完全可见的向后或向前单元格。
devise
Table Cell Layout Description -> Video Table Cell (Fix height 393) -> Content View -> Main view - (as per Content view of Table view Cell) -> Title View (0, 0, MainView.width, 57) -> Video View (0, 57, MainView.width, 200); -> Description View (0, 257, MainView.width, 136)
编码:
VideoTableCell.h
#import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @interface VideoTableCell : UITableViewCell @property (strong, nonatomic) IBOutlet UIView *viewForVideo; @property (strong, nonatomic) IBOutlet UIImageView *imgThumb; @property (strong, nonatomic) IBOutlet UIButton *btnPlay; @property (strong, nonatomic) AVPlayerItem* videoItem; @property (strong, nonatomic) AVPlayer* videoPlayer; @property (strong, nonatomic) AVPlayerLayer* avLayer; @end
VideoTableCell.m
#import "VideoTableCell.h" @implementation VideoTableCell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; return self; } - (void)layoutSubviews { [super layoutSubviews]; [self.avLayer setFrame:CGRectMake(self.viewForVideo.frame.origin.x, self.viewForVideo.frame.origin.y, self.viewForVideo.frame.size.width, self.viewForVideo.frame.size.height)]; } @end
VideoVC.h
#import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @interface VideoVC : UIViewController <UITableViewDataSource, UITableViewDelegate> @property (strong, nonatomic) IBOutlet UITableView *tblData; @end
VideoVC.m
#import "VideoVC.h" #import "VideoTableCell.h" @interface VideoVC () { NSArray *arrVideo ; bool isScrolling; int index; BOOL fullvisible ; } @end @implementation VideoVC - (void)viewDidLoad { [super viewDidLoad]; arrVideo = [[NSArray alloc]initWithObjects:@"http://video/1.mp4",@"http://video/2.mp4", @"http://video/3.mp4", @"http://video/4.mp4", @"http://video/5.mp4", nil]; fullvisible = YES; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return arrVideo.count; } -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { VideoTableCell *cell = [tableView dequeueReusableCellWithIdentifier:@"VideoTableCell"]; if (cell == nil) { cell = [[[NSBundle mainBundle] loadNibNamed:@"VideoTableCell" owner:self options:nil]objectAtIndex:0]; } int temp = [self getVisibleIndex]; if (temp == indexPath.row && fullvisible) { cell.imgThumb.hidden = YES ; //NSLog(@"fullvisible == 1"); NSURL *url = [NSURL URLWithString:[arrVideo objectAtIndex:indexPath.row]]; cell.videoItem = [AVPlayerItem playerItemWithURL:url]; cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem]; cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer]; [cell.avLayer setBackgroundColor:[UIColor whiteColor].CGColor]; // [cell.avLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; [cell.contentView.layer addSublayer:cell.avLayer]; [cell.videoPlayer play]; [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; } else { cell.imgThumb.hidden = NO ; cell.videoPlayer = nil; [cell.avLayer removeFromSuperlayer]; cell.videoItem = nil; [cell.videoPlayer pause]; } return cell ; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 393 ; } -(int)getVisibleIndex { for (NSIndexPath *indexPath in _tblData.indexPathsForVisibleRows) { CGRect cellRect = [_tblData rectForRowAtIndexPath:indexPath]; BOOL isVisible = CGRectContainsRect(_tblData.bounds, cellRect); if (isVisible) { index = (int)indexPath.row ; } } return index ; } - (void)scrollViewDidScroll:(UIScrollView *)aScrollView { NSArray* cells = _tblData.visibleCells; for (VideoTableCell* cell in cells) { NSIndexPath *path = [_tblData indexPathForCell:cell] ; index =(int) path.row; fullvisible = YES; [_tblData reloadData]; } }
每个UITableViewCell
子类都有一个prepareForReuse:
方法prepareForReuse:
所以在你的VideoTableCell
只需要添加一个方法:
-(void)prepareForReuse { [super prepareForReuse]; [self.videoPlayer play]; }
在你的控制器中实现一个委托方法: - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { [cell stopVideo]; }
并在stopVideo
只是添加[self.videoPlayer pause]
或[cell.videoPlayer stop]
在UITableView中试试这个方法
func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { // stop video } func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { // play video }
应该帮助你。
如果这不能满足您的要求,请尝试覆盖scrollViewDidScroll
更多详细信息
为UITableViewCell写一个类别来检查单元是否完全可见:
的UITableViewCell + FullyVisible
-(BOOL) isFullyVisible { UITableView *tableview = (UITableView *)[self parents:[UITableView class]]; CGRect rect = [tableview rectForRowAtIndexPath:[tableview indexPathForCell:self]]; rect = [tableview convertRect:rect toView:tableview.superview]; return CGRectContainsRect(tableview.frame, rect); }
在cellForRowAtIndexpath中:检查单元格是否完全可见。 如果细胞完全可见,则播放video,否则停止/暂停。